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

Block Hooks: Make work with modified templates/parts/patterns #5523

Conversation

ockham
Copy link
Contributor

@ockham ockham commented Oct 18, 2023

From a pair-programming session with @gziolo.

The biggest tradeoff we made in the implementation of Block Hooks was that we had to limit them to templates, template parts, and patterns that didn't have any user modifications (see #59313 for the reason). We would like to remove this limitation, so they’ll also work with user-modified templates, parts, and patterns.

The crucial problem we need to solve is to acknowledge if a user has opted to remove or persist a hooked block, so that the auto-insertion mechanism won't run again and inject an extraneous hooked block on the frontend when none is solicited.

TODO:

Consider this PR experimental; we might want to break it down into smaller pieces to land invididually:

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


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@ockham ockham self-assigned this Oct 18, 2023
@ockham
Copy link
Contributor Author

ockham commented Oct 18, 2023

If I apply the following patch to this branch, I can see that the Mini Cart block is added to the Navigation block's blockHooks attribute in the preloaded routes:

diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php
index 77c7716434..29d30017c2 100644
--- a/src/wp-includes/blocks.php
+++ b/src/wp-includes/blocks.php
@@ -772,12 +772,12 @@ function insert_hooked_blocks( &$block, $relative_position, $anchor_block_type,
                if ( ! isset( $block['attrs']['blockHooks'] ) || ! in_array( $hooked_block_type, $block['attrs']['blockHooks'] ) ) {
                        $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
                }
-               if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
+               //if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
                        if ( ! isset( $block['attrs']['blockHooks'] ) ) {
                                $block['attrs']['blockHooks'] = array();
                        }
                        $block['attrs']['blockHooks'][] = $hooked_block_type;
-               }
+               //}
        }
        return $markup;
 }
image

The attribute still seems to be filtered out on the client side (in the editor) though -- I guess we need to make the global blockHooks attribute known to the editor.

I also can't see the attribute injected into the Comment Template block (for the Like Button) yet.

Needs more tweaking, I guess 😅

@gziolo
Copy link
Member

gziolo commented Oct 18, 2023

The attribute still seems to be filtered out on the client side (in the editor) though -- I guess we need to make the global blockHooks attribute known to the editor.

Right, that would be necessary here. Unless we reuse metadata attribute that is already being injected in the editor here:

https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/hooks/metadata.js

In that case, we would need to make metadata the globally registered attribute on the server (which is probably needed anyway). The information would get stored as attributes.metadata.blockHooks.

So whatever works for you best 😀

@ockham ockham force-pushed the try/inject-block-hooks-into-modified-templates-parts-patterns branch from 1de1b5e to 8ef9462 Compare October 18, 2023 19:38
@ockham
Copy link
Contributor Author

ockham commented Oct 30, 2023

I've added some more comments to the Trac issue; the tl;dr is:

We'll go with ignoredHookedBlocks for a start.

Per discussion with @gziolo and @mtias, we'll indeed wrap the ignoredHookedBlocks property in the metadata attribute, i.e.

<!-- wp:navigation {"metadata":{"ignoredHookedBlocks":["mycommerce/mini-cart"]}} -->

@ockham
Copy link
Contributor Author

ockham commented Oct 30, 2023

On the note of the global metadata attribute: It seems that per WordPress/gutenberg#54426, it's no longer experimental 👍

Edit: Also related: WordPress/gutenberg#55194

@ockham ockham force-pushed the try/inject-block-hooks-into-modified-templates-parts-patterns branch from 8ef9462 to d7837be Compare October 30, 2023 14:47
@ockham
Copy link
Contributor Author

ockham commented Oct 30, 2023

Update: With the attribute renamed to ignoredHookedBlocks, and moved into metadata, the following patch

diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php
index 93fad3ee95..d28274ab3a 100644
--- a/src/wp-includes/blocks.php
+++ b/src/wp-includes/blocks.php
@@ -781,12 +781,12 @@ function insert_hooked_blocks( &$block, $relative_position, $anchor_block_type,
                ) {
                        $markup .= get_comment_delimited_block_content( $hooked_block_type, array(), '' );
                }
-               if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
+               //if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
                        if ( ! isset( $block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {
                                $block['attrs']['metadata']['ignoredHookedBlocks'] = array();
                        }
                        $block['attrs']['metadata']['ignoredHookedBlocks'][] = $hooked_block_type;
-               }
+               //}
        }
        return $markup;
 }

now successfully adds the information to the block in the editor 🎉

<!-- wp:navigation {"ref":4,"metadata":{"ignoredHookedBlocks":["woocommerce/mini-cart"]},"layout":{"type":"flex","setCascadingProperties":true,"justifyContent":"right"}} /-->

@ockham
Copy link
Contributor Author

ockham commented Oct 30, 2023

Also working for lastChild insertion, although it seems like it's attaching the info to the wrong block 🤔

<!-- wp:comment-template -->
<!-- wp:columns {"metadata":{"ignoredHookedBlocks":["ockham/like-button"]},"style":{"spacing":{"margin":{"bottom":"var:preset|spacing|40"}}}} -->
<div class="wp-block-columns" style="margin-bottom:var(--wp--preset--spacing--40)"><!-- wp:column {"width":"40px"} -->
<div class="wp-block-column" style="flex-basis:40px"><!-- wp:avatar {"size":40,"style":{"border":{"radius":"20px"}}} /--></div>
<!-- /wp:column -->

@ockham
Copy link
Contributor Author

ockham commented Oct 31, 2023

Better now:

<!-- wp:comment-template {"metadata":{"ignoredHookedBlocks":["ockham/like-button"]}} -->

(Also, no more patching needed -- the PR now Just Works™️)

@ockham ockham force-pushed the try/inject-block-hooks-into-modified-templates-parts-patterns branch from 2ad2683 to f5e4b6f Compare November 1, 2023 10:52
@ockham ockham changed the title Block Hooks: Add blockHooks global attribute to anchor blocks Block Hooks: Make work with modified templates/parts/pattern Nov 1, 2023
@ockham ockham changed the title Block Hooks: Make work with modified templates/parts/pattern Block Hooks: Make work with modified templates/parts/patterns Nov 1, 2023
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.

This is shaping up nicely. I'm surprised how little changes are necessary to open the logic for templates and template parts modified by the site editor's user.

@@ -757,6 +757,44 @@ function get_hooked_blocks() {
return $hooked_blocks;
}

function insert_hooked_blocks( $relative_position, &$anchor_block, $hooked_blocks, $context ) {
Copy link
Member

Choose a reason for hiding this comment

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

Minor: &$anchor_block might go as a first param as it's the only one that can get modified. It's probably something we can discuss in #5609.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, thank you!

@@ -894,6 +894,14 @@ function _build_block_template_result_from_post( $post ) {
}
}

$hooked_blocks = get_hooked_blocks();
Copy link
Member

Choose a reason for hiding this comment

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

That would be quite convenient for all templates stored in the database 👍🏻


// TODO: The following is only needed for the REST API endpoint.
// Ideally, the code should thus be moved into the controller.
if ( ! isset( $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any issue with running it always? It's a simple operation, so I don't expect it would impact the front end. I would be in favor of keeping it simple unless I miss something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No issue, other than it adds a few bytes per block (and it might be somewhat confusing for people). I just thought if we revisit #5514 (which requires different treatment of frontend and REST API), we might also look into this. Definitely okay to leave it in though.

src/wp-includes/class-wp-block-type.php Outdated Show resolved Hide resolved
@ockham ockham force-pushed the try/inject-block-hooks-into-modified-templates-parts-patterns branch 2 times, most recently from 496f2ff to 39c69a3 Compare November 6, 2023 15:00
@ockham
Copy link
Contributor Author

ockham commented Nov 9, 2023

Some notes:

  • Template Part block: Use _build_block_template_result_from_post gutenberg#55811 has been merged; we might want to do a package sync to pull in those changes, as we'll need them for hooked block insertion into modified templates. (I hope that a package sync won't have any adversary side effects, e.g. if other blocks rely on PHP code that's not in Core yet? Might be less risky since we're only at the beginning of the release cycle, and there's not too much stuff yet in GB's lib/compat/wordpress-6.5. Curious to hear your thoughts @gziolo)
  • In a similar vein, we need to test the Block Hooks UI with this PR. We will need to update how it works, which has to be done in GB. Depending on the logic we'll have to implement there (to possibly accommodate both for the "old" way of hooked block insertion and the "new" way), this might raise the question if we should also implement insertion into modified templates in GB first 🤔 (We will probably be able to make an informed decision based on what those changes to the UI logic will need to look like.)

@ockham ockham force-pushed the try/inject-block-hooks-into-modified-templates-parts-patterns branch from 839ee3b to f29ba55 Compare November 28, 2023 09:52
@ockham
Copy link
Contributor Author

ockham commented Nov 30, 2023

Closing in favor or #5712.

@ockham ockham closed this Nov 30, 2023
@ockham ockham deleted the try/inject-block-hooks-into-modified-templates-parts-patterns branch November 30, 2023 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants