Skip to content

fix: find synced patterns at any depth when registering block assets - #2987

Open
johansolve wants to merge 1 commit into
Codeinwp:masterfrom
johansolve:fix/nested-synced-pattern-assets
Open

fix: find synced patterns at any depth when registering block assets#2987
johansolve wants to merge 1 commit into
Codeinwp:masterfrom
johansolve:fix/nested-synced-pattern-assets

Conversation

@johansolve

Copy link
Copy Markdown

Closes #2984.

Summary

Registration::enqueue_dependencies() scanned for reusable blocks (core/block) by filtering the flat list returned by parse_blocks(), so only patterns sitting at the top level of the content were found. A synced pattern nested inside a Group — the usual way people place one — was never seen, and none of the blocks it holds got their assets registered.

Because the handles are registered conditionally, core's own render-time enqueue then no-ops on an unregistered handle, so the block ends up with neither its stylesheet nor its script. For the Form block that is not just cosmetic: submission happens in JS, so the form cannot be submitted at all.

The collection step now walks the whole tree, gathering each pattern ID once. Extracted as Registration::get_reusable_block_ids(), public static like the neighbouring get_active_widgets_content(), so the behaviour is unit-testable without a built build/ directory.

Since patterns can contain patterns, enqueue_dependencies() still recurses per ID as before — this only changes which IDs it is handed.

Test instructions

  1. Add a Form block to a page, then create a synced pattern from it.
  2. On a page, place that pattern inside a Group block.
  3. View the page on the frontend.
  4. Before this change: otter-form-style and build/blocks/form.js are both absent, .otter-form__container falls back to display: block, and submitting does nothing. After: both load and the form submits.
  5. Confirm the top-level case still works by placing the same pattern directly in the page root.

Unit tests cover a pattern nested in a Group, patterns collected from several levels without duplicates, and content with no usable pattern (including a core/block without a ref).

I could not run the PHPUnit suite locally — it needs wp-env, and Docker was unavailable on this machine — so the new tests have not been executed. composer run lint (phpcs) passes on both changed files, and phpstan reports the same 22 pre-existing errors in class-registration.php before and after, so nothing new was introduced. The behaviour itself is verified in a real WordPress 7.0.4 install: two otherwise identical pages against the same pattern, nested versus top level, before and after the patch.

Checklist before the final review

  • Included E2E or unit tests for the changes in this PR.
  • Visual elements are not affected by independent changes.
  • It is at least compatible with the minimum WordPress version.
  • It loads additional script in frontend only if it is required.
  • Does not impact the Core Web Vitals.
  • In case of deprecation, old blocks are safely migrated.
  • It is usable in Widgets and FSE.
  • Copy/Paste is working if the attributes are modified.

Notes on the checklist: no attributes, markup or visual elements change, so the deprecation and copy/paste items do not apply. Assets are still only registered for blocks the page actually uses — the change is which patterns get scanned, not how much is loaded. The widgets path (enqueue_dependencies( 'widgets' )) goes through the same collection step and is fixed along with it.


Created with help of Claude Code.

The scan for reusable blocks only looked at the top level of the parsed
block tree, so a synced pattern nested inside another block was never
found and the blocks it holds got none of their assets registered. For
the Form block that also means no frontend script, so the form cannot be
submitted.

Walk the whole tree instead, collecting each pattern ID once.
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.

Block assets are never enqueued when a block sits inside a nested synced pattern

1 participant