Make WordPress Core

Opened 22 months ago

Closed 8 months ago

Last modified 5 months ago

#62715 closed enhancement (fixed)

Block Hooks: Apply to content-like Custom Post Types

Reported by: Bernhard Reiter Owned by: audrasjb
Priority: normal Milestone: 7.0
Component: General Version:
Severity: normal Keywords: has-patch has-test-info add-to-field-guide needs-dev-note
Cc: Focuses:

Description

Per [59523] and [59543], Block Hooks are applied to post content and synced patterns, respectively.

This involved adding update_ignored_hooked_blocks_postmeta to the rest_pre_insert_* hook (for the page, post, and wp_block post types), and insert_hooked_blocks_into_rest_response to the rest_prepare_* hook (for the same post types).

The downside of adding those filters to those hooks on an individual post type basis is that Block Hooks are only applied to those post types, but not to user-defined Custom Post Types; extenders would have to do so themselves.

Arguably, they shouldn't have to; Block Hooks should work out of the box for a CPT (assuming that it is a "content-like" CPT). We might thus want to consider inlining the code from those two functions into the Posts REST API controller (namely, into the prepare_item_for_database and prepare_item_for_response methods, respectively). We can consider adding some criteria to make sure that Block Hooks are aren't accidentally applied to ancillary post types, such as the ones used for Global Styles.

Furthermore, the two aforementioned functions now contain logic to map a given post type (e.g. post or wp_block) to the corresponding block type (core/post-content and core/block, in this example). This is required so that the block markup can be temporarily wrapped in a block of that type, thus allowing Block Hooks to insert hooked blocks as the first or last child of the containing block.

These mappings should be filterable by the user, so that the user can extend them to include custom-defined post types and block types, respectively -- or to remove mappings, if needed.

(Stretch goal: In the future, we might want to use these mappings to (partially) unify the implementations of blocks like Post Content, Synced Pattern, and possibly Navigation and Template Part, which all render content that they get separately from the database.)

Change History (14)

This ticket was mentioned in ​Slack in #core by audrasjb. ​View the logs.


20 months ago

#2 @audrasjb
20 months ago

  • Keywords needs-patch added
  • Milestone 6.8 → 6.9

As per today's bugscrub: moving to milestone 6.9 as this enhancement ticket still needs a patch.

This ticket was mentioned in ​PR #9245 on ​WordPress/wordpress-develop by ​@iamadisingh.


15 months ago
#3

  • Keywords has-patch added; needs-patch removed

Move Block Hooks logic from individual post type filters to REST controller Fixes #62715.

Trac ticket: https://core.trac.wordpress.org/ticket/62715

---

#4 @iamadisingh
15 months ago

  • Keywords needs-testing added

#5 @iamadisingh
15 months ago

Test Report

Description

This report validates whether the indicated patch works as expected.

Patch tested: ​https://github.com/WordPress/wordpress-develop/pull/9245

Environment

  • WordPress: 6.9-alpha-60093-src
  • PHP: 8.2.28
  • Server: nginx/1.27.3
  • Database: mysqli (Server: 8.4.5 / Client: mysqlnd 8.2.28)
  • Browser: Chrome 138.0.0.0
  • OS: macOS
  • Theme: Twenty Twenty-Five 1.2
  • MU Plugins: None activated
  • Plugins:
    • Test Block Hooks
    • Test Reports

Actual Results

  1. ✅ Issue resolved with patch.

Additional Notes

  • Added this plugin for registering a new cpt and registered block with block_hooks
    <?php
    /**
     * Plugin Name: Test Block Hooks
     * Description: Tests Block Hooks
     */
    
    function register_test_cpt() {
        register_post_type('portfolio', array(
            'labels' => array(
                'name' => 'Portfolio',
                'singular_name' => 'Portfolio Item',
            ),
            'public' => true,
            'show_in_rest' => true,
            'supports' => array('title', 'editor', 'thumbnail'),
            'has_archive' => true,
        ));
    }
    add_action('init', 'register_test_cpt');
    
    function register_test_hooked_block() {
        register_block_type('test/social-share', array(
            'block_hooks' => array(
                'core/post-content' => 'after', // Hook after post content
            ),
            'render_callback' => function($attributes, $content, $block) {
                return '<div class="social-share" style="background: #f0f0f0; padding: 10px; margin: 10px 0;">
                    🔗 <strong>Share this content!</strong> 
                    <small>(Hooked Block - Post Type: ' . get_post_type() . ')</small>
                </div>';
            },
        ));
    }
    add_action('init', 'register_test_hooked_block');
    
    function test_custom_block_hooks_filter($post_types, $current_post_type, $post) {
        error_log('Block Hooks Filter Called: ' . $current_post_type . ' - Post Types: ' . implode(', ', $post_types));
        
        if (!in_array('portfolio', $post_types)) {
            $post_types[] = 'portfolio';
        }
        
        return $post_types;
    }
    add_filter('rest_block_hooks_post_types', 'test_custom_block_hooks_filter', 10, 3);
    

Supplemental Artifacts

Default Posts: ​https://ibb.co/zVNDhVDP

New CPT: ​https://ibb.co/HkMt7nH

This ticket was mentioned in ​Slack in #core by welcher. ​View the logs.


13 months ago

This ticket was mentioned in ​Slack in #core by wildworks. ​View the logs.


12 months ago

#8 @wildworks
12 months ago

  • Milestone 6.9 → 7.0

This ticket was featured on today's 6.9 Bug Scrub.

Let's punt this ticket to 7.0. If there's no movement in that cycle, let's punt it to feature-release.

This ticket was mentioned in ​Slack in #core-test by nikunj8866. ​View the logs.


11 months ago

#10 @r1k0
11 months ago

Test Report

Description

This report validates whether the indicated patch works as expected.

Patch tested: ​https://github.com/WordPress/wordpress-develop/pull/9245

Environment

  • WordPress: 6.9-RC3-61308
  • PHP: 8.3.23
  • Server: Apache/2.4.43 (Unix)
  • Database: mysqli (Server: 8.0.35 / Client: mysqlnd 8.3.23)
  • Browser: Firefox 145.0
  • OS: Ubuntu
  • Theme: Twenty Twenty-Five 1.3
  • MU Plugins: None activated
  • Plugins:
    • Block Hook Test
    • Test Reports 1.2.1

Actual Results

  1. ✅ Issue resolved with patch.

Additional Notes

-Create a plugin folder (named:Block Hook Test) and add this code to a file (named:blockhook.php). Add the plugin in the "wp-content/plugins" folder and activate the plugin.

<?php
/**
 * Plugin Name: Block Hook Test
 * Description: A test plugin to test block hooks for a custom post type in WordPress.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

function blockhooks_test_register_cpt() {
    register_post_type( 'book', array(
        'labels' => array(
            'name' => __('Books'),
            'singular_name' => __('Book Item'),
        ),
        'public' => true,
        'show_in_rest' => true,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
        'has_archive' => true,
        'show_in_menu' => true,
    ) );
}
add_action( 'init', 'blockhooks_test_register_cpt' );

function blockhooks_test_allow_cpt_for_hooks( $post_types, $current_post_type, $post ) {
        if ( ! in_array( 'book', $post_types, true ) ) {
                $post_types[] = 'book';
        }
        return $post_types;
}
add_filter( 'rest_block_hooks_post_types', 'blockhooks_test_allow_cpt_for_hooks', 10, 3 );

function blockhooks_test_register_block() {
        register_block_type('blockhooks-test/added-block', array(
            'block_hooks' => array(
                'core/post-content' => 'after',
            ),
            'render_callback' => 'blockhooks_test_render_block',
        ) );
}
add_action( 'init', 'blockhooks_test_register_block' );

function blockhooks_test_render_block( $attributes = array() ) {
    $post_type = get_post_type();

        $html  = '<div class="blockhooks-test-injected" style="padding:12px;border-left:4px solid #c00;margin:1em 0;background:#eee5e5;">';
        $html .= '<strong>Added by Block Hooks:</strong> This block was inserted automatically by the BlockHooks Test Plugin.';
        $html .= '<em style="color:#3410b7">(Post Type: ' . esc_html( $post_type ) . ')</em>';
    $html .= '</div>';
        return $html;
}
  • Reset permalinks after activating the plugin.

Supplemental Artifacts

Post Type(Post): https://i.ibb.co/n54780g/post.png
Custom Post Type(Book): https://i.ibb.co/6RTh5q73/book-cpt.png

Last edited 11 months ago by r1k0 (previous) (diff)

#11 @nikunj8866
11 months ago

  • Keywords has-test-info added; needs-testing removed

#12 @audrasjb
8 months ago

  • Owner set to audrasjb
  • Resolution → fixed
  • Status new → closed

In 61707:

Editor: Enable Block Hooks for content-like Custom Post Types.

This changeset moves the Block Hooks logic from individual post type filters to the REST controller.

Props bernhard-reiter, iamadisingh, audrasjb, r1k0.
Fixes #62715.

#13 @audrasjb
7 months ago

  • Keywords add-to-field-guide needs-dev-note added

This is worth mentioning in the Field Guide.
Also adding needs-dev-note just in case we can mention it in a more general note. Maybe it czan even have its own dev note?

#14 @johnbillion
5 months ago

In 62430:

Docs: Remove duplicate documentation for the rest_block_hooks_post_types hook.

See #62715, #64896

Note: See TracTickets for help on using tickets.