Make WordPress Core

#59776 closed defect (bug) (fixed)

Block Hooks: Allow traversal callbacks to modify parent block

Reported by: bernhard-reiter's profile Bernhard Reiter Owned by: bernhard-reiter's profile Bernhard Reiter
Milestone: 6.4 Priority: normal
Severity: normal Version: 6.4
Component: Editor Keywords: has-patch commit dev-reviewed
Focuses: Cc:

Description

tl;dr: In 6.5, we'll need arguments to two functions introduced during the 6.4 cycle to become references. Since that can be deemed a back-compat breaking change, I'm suggesting to make that change already.


The callbacks returned by make_before_block_visitor and make_after_block_visitor, respectively (which are passed as arguments to traverse_and_serialize_block(s)) currently accept three arguments, all of which are block arrays (i.e. with properties blockName, attrs, etc.):

  • A reference to the block they're currently visiting, &$block;
  • the block's $parent_block; and
  • the $previous block (for make_before_block_visitor), or the $next block (for make_after_block_visitor), respectively.

Those arguments are passed to the "block visitor" callbacks by traverse_and_serialize_block(s) during traversal. The block that the callback is currently visiting is passed by reference to allow modifying it, which is e.g. used to inject the theme attribute into Template Part blocks.

One major limitation with Block Hooks is that they currently only work with templates, parts, and patterns that don't have any user modifications (i.e. that come straight from the corresponding theme files, rather than the DB). For WP 6.5, we're planning to change that to also make Block Hooks work for templates, parts, and patterns that do have user modifications: #59646.

The way we'll make this work is by storing an attribute on the "anchor" block. This is currently being developed in https://github.com/WordPress/wordpress-develop/pull/5523.

While working on that PR, I noticed that that means that we'll also need to allow the aforementioned callbacks to modify not only the currently visited $block, but also the $parent_block -- i.e. to pass the latter argument by reference, too. This is consistent with the requirement of adding an attribute to an anchor block, as it's not only the currently visited block that can serve as an anchor block (in the case of before or after sibling insertion), but also its parent (for first_child and last_child insertion).

Per discussion with @hellofromtonya, changing the $parent_block argument to become a reference can be considered a backwards-compatibility breaking change. I'm thus suggesting to make that change already as part of 6.4, which is the cycle where the relevant functions were first introduced. This should have no impact on existing code, since nothing currently relies on $parent_block remaining unmodified by the respective callback, nor is anything currently modifying that argument.

Change History (11)

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


11 months ago

#2 @hellofromTonya
11 months ago

  • Type changed from enhancement to defect (bug)
  • Version set to trunk

Thanks for opening this ticket @bernhard-reiter. Changing is type to defect, as it could be considered a bug for enhancement needs in 6.5.

As these functions were introduced in the 6.4 cycle, makes sense to adjust the function parameter(s) to be "by reference" to avoid a possible BC break in the next cycle.

#3 @hellofromTonya
11 months ago

  • Component changed from General to Editor
  • Keywords needs-patch added

#4 @Bernhard Reiter
11 months ago

I filed a PR and added this ticket's URL to its description, but Trac doesn't seem to have picked it up. Anyway, here goes: https://github.com/WordPress/wordpress-develop/pull/5598

#5 @hellofromTonya
11 months ago

  • Keywords has-patch changes-requested added; needs-patch removed

#6 @hellofromTonya
11 months ago

  • Keywords commit added; changes-requested removed

The patch: https://github.com/WordPress/wordpress-develop/pull/5598

LGTM and sharing my approval comment:

As explained, these changes are needed as continued iteration for 6.5 revealed pass by reference is required. Doing these changes avoids a BC break in the 6.5 cycle.

The change also includes a little bit of girl scouting to improve the @param documentation.

Marking for commit.

@bernhard-reiter once committed to trunk, please add the dev-feedback keyword to alert a 2nd committer (like me) to review for backporting to the 6.4 branch. Thanks :)

#7 @Bernhard Reiter
11 months ago

  • Owner set to Bernhard Reiter
  • Resolution set to fixed
  • Status changed from assigned to closed

In 57038:

Block Hooks: Allow traversal callbacks to modify parent block.

The callbacks returned by make_before_block_visitor and make_after_block_visitor, respectively, (which are passed as arguments to traverse_and_serialize_block(s)) currently accept three arguments, all of which are block arrays (i.e. with properties blockName, attrs, etc.):

  • A reference to the block they're currently visiting, &$block;
  • the block's $parent_block; and
  • the $previous block (for make_before_block_visitor), or the $next block (for make_after_block_visitor), respectively.

Those arguments are passed to the "block visitor" callbacks by traverse_and_serialize_block(s) during traversal. The block that the callback is currently visiting is passed by reference to allow modifying it, which is e.g. used to inject the theme attribute into Template Part blocks.

One major limitation of Block Hooks is that they currently only work with templates, parts, and patterns that don't have any user modifications (i.e. that come straight from the corresponding theme files, rather than from the database). For WordPress 6.5, it is planned to change that to make Block Hooks work for templates, parts, and patterns that do have user modifications: #59646.

This will be implemented by storing an attribute on the "anchor" block. While working on that feature, it was found that the aforementioned callbacks will need to modify not only the currently visited $block, but also the $parent_block -- i.e. that the latter argument needs to be passed by reference as well. This is consistent with the requirement of adding an attribute to an anchor block, as it's not only the currently visited block that can serve as an anchor block (in the case of before or after sibling insertion), but also its parent (for first_child and last_child insertion).

If the $parent_block argument were to be changed to become a reference in a later WordPress version, this could be considered a backwards-compatibility breaking change. For this reason, this change is instead proposed for 6.4 already, which is the cycle during which the relevant functions were first introduced. This should have no impact on existing code, since nothing currently relies on $parent_block remaining unmodified by the respective callback, nor is anything currently modifying that argument.

Props hellofromTonya.
Fixes #59776.

#8 @Bernhard Reiter
11 months ago

  • Keywords dev-feedback added
  • Resolution fixed deleted
  • Status changed from closed to reopened

Reopening to request a second committer's review and approval to backport to the 6.4 branch :)

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


11 months ago

#10 @hellofromTonya
11 months ago

  • Keywords dev-reviewed added; dev-feedback removed

Marking [57038] ready for backport to the 6.4 branch.

#11 @Bernhard Reiter
11 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 57039:

Block Hooks: Allow traversal callbacks to modify parent block.

The callbacks returned by make_before_block_visitor and make_after_block_visitor, respectively, (which are passed as arguments to traverse_and_serialize_block(s)) currently accept three arguments, all of which are block arrays (i.e. with properties blockName, attrs, etc.):

  • A reference to the block they're currently visiting, &$block;
  • the block's $parent_block; and
  • the $previous block (for make_before_block_visitor), or the $next block (for make_after_block_visitor), respectively.

Those arguments are passed to the "block visitor" callbacks by traverse_and_serialize_block(s) during traversal. The block that the callback is currently visiting is passed by reference to allow modifying it, which is e.g. used to inject the theme attribute into Template Part blocks.

One major limitation of Block Hooks is that they currently only work with templates, parts, and patterns that don't have any user modifications (i.e. that come straight from the corresponding theme files, rather than from the database). For WordPress 6.5, it is planned to change that to make Block Hooks work for templates, parts, and patterns that do have user modifications: #59646.

This will be implemented by storing an attribute on the "anchor" block. While working on that feature, it was found that the aforementioned callbacks will need to modify not only the currently visited $block, but also the $parent_block -- i.e. that the latter argument needs to be passed by reference as well. This is consistent with the requirement of adding an attribute to an anchor block, as it's not only the currently visited block that can serve as an anchor block (in the case of before or after sibling insertion), but also its parent (for first_child and last_child insertion).

If the $parent_block argument were to be changed to become a reference in a later WordPress version, this could be considered a backwards-compatibility breaking change. For this reason, this change is instead proposed for 6.4 already, which is the cycle during which the relevant functions were first introduced. This should have no impact on existing code, since nothing currently relies on $parent_block remaining unmodified by the respective callback, nor is anything currently modifying that argument.

Reviewed by hellofromTonya.
Merges [57038] to the 6.4 branch.

Props hellofromTonya.
Fixes #59776.

Note: See TracTickets for help on using tickets.