Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Synced Patterns: Apply Block Hooks #68058

Merged
merged 5 commits into from
Dec 19, 2024

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Dec 17, 2024

What?

Apply Block Hooks to synced patterns (i.e. core/block).

Follow-up to #67272 and WordPress/wordpress-develop#7898. See WordPress/wordpress-develop#7898 (comment) for more context.

Why?

For consistency with post content, to which Block Hooks are now also applied.

How?

By applying the same technique as to other post types, e.g. post or wp_navigation. See #67272 for a recent example.

Follow-up

In a follow-up PR, I'll add a filter for the post type/block type mappings, so that they can be customized and used for CPTs.

Testing Instructions

Start by installing the following plugin, but do not activate it yet:

Plugin code
<?php
/**
 * Plugin Name:       Insert Separator blocks Before Headings.
 * Description:       Block Hooks demo plugin that inserts Separator blocks before Heading blocks.
 * Version:           0.1.0
 * Requires at least: 6.7
 */

defined( 'ABSPATH' ) || exit;

function insert_separators_before_headings( $hooked_blocks, $position, $anchor_block, $context ) {
	if ( ! $context instanceof WP_Post ) {
		return $hooked_blocks;
	}

	if (
		( $anchor_block === 'core/heading' && $position === 'before' ) ||
		( $anchor_block === 'core/block' && $position === 'last_child' )
	) {
		$hooked_blocks[] = 'core/separator';
	}

	return $hooked_blocks;
}
add_filter( 'hooked_block_types', 'insert_separators_before_headings', 10, 4 );

function set_separator_block_inner_html( $hooked_block, $hooked_block_type, $relative_position, $anchor_block ) {
	if (
		( $anchor_block['blockName'] === 'core/heading' && 'before' === $relative_position ) ||
		( $anchor_block['blockName'] === 'core/block' && 'last_child' === $relative_position )
	) {
        $hooked_block['innerContent'] = array( '<hr class="wp-block-separator has-alpha-channel-opacity"/>' );
	}

	return $hooked_block;
}
add_filter( 'hooked_block_core/separator', 'set_separator_block_inner_html', 10, 4 );
  • Create a new post that contains one heading and one paragraph of text.
  • Select those two blocks. From the block toolbar's three-horizontal-dots menu, select "Create Pattern".
  • Give the pattern a name you'll easily remember. Keep the "Synced" toggle on.
  • Save that post, and view it on the frontend. Keep it open in a tab.
  • Activate the plugin.
  • Go back to the tab with the post (on the frontend). Reload.
  • Verify that before the heading, a separator (i.e. a horizontal line) has been inserted.
  • Also verify that another separator has been inserted as the synced pattern's last child block (i.e. after the paragraph block).
  • Open the post in the editor, and verify that the separators are also present there.
  • Click on the synced pattern, and from its block toolbar, select "Edit original".
  • Modify the separators -- e.g. move one around and remove the other. Save the synced pattern.
  • Reload the post on the frontend again. Verify that the changes you made in the editor are respected.

Screenshots or screencast

block-hooks-with-synced-patterns

@ockham ockham added [Type] Enhancement A suggestion for improvement. [Feature] Block hooks labels Dec 17, 2024
@ockham ockham self-assigned this Dec 17, 2024
Copy link

github-actions bot commented Dec 17, 2024

Flaky tests detected in 256ebad.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/12378234118
📝 Reported issues:

@@ -170,7 +170,7 @@ function gutenberg_apply_block_hooks_to_post_content( $content ) {
* @return WP_REST_Response The response object.
*/
function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {
if ( empty( $response->data['content']['raw'] ) || empty( $response->data['content']['rendered'] ) ) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that synced patterns don't have rendered content set, so I had to loosen the criterion here.

@ockham ockham marked this pull request as ready for review December 18, 2024 11:00
@ockham ockham requested a review from gziolo December 18, 2024 11:00
Copy link

github-actions bot commented Dec 18, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: ockham <bernhard-reiter@git.wordpress.org>
Co-authored-by: gziolo <gziolo@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@fabiankaegy fabiankaegy added the Needs Dev Note Requires a developer note for a major WordPress release cycle label Dec 18, 2024
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't that much code to support Synced Patterns. Code looks good and it's similar to what I saw for other similar blocks updated recently. I will give it a round of testing next.

@@ -206,6 +208,11 @@ function gutenberg_insert_hooked_blocks_into_rest_response( $response, $post ) {

$response->data['content']['raw'] = $content;

// If the rendered content was previously empty, we leave it like that.
if ( empty( $response->data['content']['rendered'] ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes perfect sense together with other changes 👍🏻

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works like a charm! So great to see all these enhancements 💯

@@ -87,6 +87,26 @@ function render_block_core_block( $attributes ) {
add_filter( 'render_block_context', $filter_block_context, 1 );
}

$ignored_hooked_blocks = get_post_meta( $attributes['ref'], '_wp_ignored_hooked_blocks', true );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find a better place, so I will ask here. How feasible would it be to move the logic to apply_block_hooks_to_content in WordPress core? A very similar logic exists now in a few places. As the helper function gets the current post object as param, it should be able to handle everything as it happens inside the rest_pre_insert_{$post_type} filter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hah, I just had a similar thought yesterday!

I'll need to check if we can really absorb this logic into apply_block_hooks_to_content. Note that templates and template parts are still handled quite differently from posts, synced patterns, and navigation blocks:

  1. They're instances of the WP_Block_Template class rather than WP_Post.
  2. While first/last child insertion is implemented for template parts, it is not implemented for templates. (The reason is that there is a Template Part block, core/template-part, that can be used as an anchor block; but of course, there's no Template block, so it cannot be used as an anchor block for Block Hooks.)
  3. I need to think a bit more about patterns.

Anyway, I'll file a ticket for this and will look into it in January 😊

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're instances of the WP_Block_Template class rather than WP_Post.

I missed the nuance of the templates. Anyway, it could still be context-based, so the additional logic would only run if the WP_Post instance is provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I'll file a ticket for this and will look into it in January 😊

https://core.trac.wordpress.org/ticket/62716

@ockham ockham merged commit 9034196 into trunk Dec 19, 2024
81 checks passed
@ockham ockham deleted the update/apply-block-hooks-to-synced-pattens branch December 19, 2024 12:29
@github-actions github-actions bot added this to the Gutenberg 20.0 milestone Dec 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block hooks Needs Dev Note Requires a developer note for a major WordPress release cycle [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants