Skip to content

Theme-registered pattern inserts as a synced pattern when wrapped in a single Group block #79795

Closed

Description

@SteveRyan-ASU

Description

Theme-registered block patterns appear to be classified differently based solely on whether the pattern has a single root wrapper block.

A pattern consisting of multiple top-level blocks inserts as a normal (unsynced) pattern, with all blocks immediately editable.

Adding a single core/group wrapper around the exact same content causes the pattern to insert as a synced/content-only pattern that must be detached before the layout can be edited.

No pattern metadata, registration code, or editor settings are changed between the two versions. The only difference is the addition of a top-level Group block.

This behavior was observed after upgrading to WordPress 7.0.

Expected behavior

Both patterns should behave identically when inserted unless the pattern is explicitly registered or created as a synced pattern.

Actual behavior

Adding a single top-level core/group wrapper changes the inserted pattern into a synced pattern requiring Detach before editing the structure.

Step-by-step reproduction instructions

  • Create a theme-registered block pattern (PHP pattern file or register_block_pattern()).
  • Populate it with multiple top-level blocks (for example: Heading → Columns → Buttons).
  • Insert the pattern into the editor.
  • Observe that the inserted blocks are immediately editable.
  • Modify only the pattern structure by wrapping the entire contents in a single core/group block.
  • Register the modified pattern.
  • Insert the modified pattern into the editor.
  • Observe that the pattern is now inserted as a synced/content-only pattern with a Detach action.

Screenshots, screen recording, code snippet

No response

Environment info

WP Version v7.0 + v7.0 RC1 (Beta testing)
Gutenberg plugin not enabled on the install so the version there should be whatever ships with the core version of WP.

Please confirm that you have searched existing issues in the repo.

  • Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

  • Yes

Please confirm which theme type you used for testing.

  • Block
  • Classic
  • Hybrid (e.g. classic with theme.json)
  • Not sure

Activity

  1. carolinan commented on Jul 13, 2026

    @carolinan
    Contributor

    Hi,
    I think this may be they key confusion:

    Adding a single core/group wrapper around the exact same content causes the pattern to insert as a synced/content-only pattern that must be detached before the layout can be edited.

    Can you provide some screenshots? I want to understand because I believe you are describing two different features.

    A synced pattern is saved in the database in their custom post type, not only the post content. That should not happen simply by inserting a pattern from a theme.

  2. carolinan commented on Jul 22, 2026

    @carolinan
    Contributor

    Hi @SteveRyan-ASU Are you able to add any more details?

  3. SteveRyan-ASU commented on Jul 22, 2026

    @SteveRyan-ASU
    Author

    Hello there. Yep, I made a little explainer video about what I'm seeing here.

    gutenberg-issue-79795.mp4

    Assets needed to recreate this in any theme would be the two pattern PHP templates here and possibly a declaration of the pattern category mentioned in the headers of both of the files. The files are included as links below but I copy/pasted the text here in this comment just for clarity. They can be inserted into the /patterns folder of any theme and should automatically be registered.

    <?php
    /**
     * Title: Simple headline, image, paragraph
     * Slug: pitchfork/simple-headline-image-paragraph
     * Categories: gh-issue-79795
     * Inserter: true
     */
    ?>
    
    <!-- wp:heading {"level":2} -->
    <h2>Sample Headline</h2>
    <!-- /wp:heading -->
    
    <!-- wp:image {"sizeSlug":"large","linkDestination":"none"} -->
    <figure class="wp-block-image size-large"><img src="https://picsum.photos/1200/800" alt="Sample image" /></figure>
    <!-- /wp:image -->
    
    <!-- wp:paragraph -->
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nisl at elit gravida facilisis.</p>
    <!-- /wp:paragraph -->
    
    <?php
    /**
     * Title: Wrapped headline, image, paragraph
     * Slug: pitchfork/wrapped-headline-image-paragraph
     * Categories: gh-issue-79795
     * Inserter: true
     */
    ?>
    
    <!-- wp:group -->
    <div class="wp-block-group">
    	<!-- wp:heading {"level":2} -->
    	<h2>Sample Headline</h2>
    	<!-- /wp:heading -->
    
    	<!-- wp:image {"sizeSlug":"large","linkDestination":"none"} -->
    	<figure class="wp-block-image size-large"><img src="https://picsum.photos/1200/800" alt="Sample image" /></figure>
    	<!-- /wp:image -->
    
    	<!-- wp:paragraph -->
    	<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nisl at elit gravida facilisis.</p>
    	<!-- /wp:paragraph -->
    </div>
    <!-- /wp:group -->
    

    The following pattern category registration is optional but useful to keep things organized as in the demo video.

    register_block_pattern_category(
        'gh-issue-79795',
        array(
            'label' => 'GH Issue 79795',
        )
    );
    

    When you wire everything together and then deploy both patterns on the screen, the result is that the "unwrapped" pattern (the one with no explicit group block) places the blocks into the editor but allows them to be edited freely, reorganized, etc. Where as the pattern that has an explicit block "wrapping" all of the other elements within (a core/group block here), results in the pattern truly functioning as a pattern. It comes complete with the lock/unlock mechanism and the more restricted number of settings per block.

    Image Image

    It is unclear if this behavior was intensional or possibly unavoidable based on how patterns work. (For a pattern to exist, it needs to be invoked on a specific block, right?) But, the behavior observed in practice here was that some of the stored patterns in our pattern library within our theme exhibited this behavor and some did not, making it difficult to communicate to our users which patterns were really "patterns" when coming from the library.

  4. carolinan commented on Jul 23, 2026

    @carolinan
    Contributor

    @SteveRyan-ASU Thank you.

    No, this has nothing to do with synced patterns. Synced patterns are the ones that you can insert multiple times across a site and then you update all copies of the pattern from one location. They also look different in the interface.

    Both the patterns that you showed are truly functioning like a pattern and all of the blocks can be locked individually. That is not related to or limited to using a group.

    Opinions:
    The group makes it easier for developers because you can add ways to identify which pattern has been used.
    For example you can add the pattern name or a CSS class to the wrapper and customise the pattern and it's content.

    The group makes it easier for users: especially if you name them so that it shows in the list view.
    It is easier to see what is part of the pattern and not.
    The pattern can be moved as one section, one unit, instead of having to select individual blocks and try to copy or drag them.

    The "Edit pattern" is not a bug. It might be somewhat annoying, and I'm not 100% sure why it was added, but at least if you look at it that way, it makes it more difficult for the user to break it because there is intentional friction.

  5. SteveRyan-ASU commented on Jul 23, 2026

    @SteveRyan-ASU
    Author

    Understood that it's not a bug to have the "Edit pattern" button display in the sidebar. I actually like that improvement as it makes the locking/unlocking of a pattern much easier to understand and not "hidden" behind a lock icon in the block picker. =)

    From my perspective, this is what I'm concerned with.

    • I registered both sets of blocks within my theme under the folder called /patterns
    • I was able to insert both sets of blocks by using the UI interface within the block editor marked as "patterns"
    • One set of blocks was actually treated as a pattern (movement locked with the edit pattern button visible) and the other was not.
    • The only noticeable difference between the two sets of blocks was the presence of a "wrapping" element for the block pattern metadata to attach to. When the wrapping element is missing, the set of blocks is not explicitly treated as a pattern.

    This also holds true if the pattern that is being created is done entirely within the block editor. (As opposed to in the codebase.)

    Try it:

    • Add an image block, a paragraph block and a heading in sequence to a blank page or post. Make sure they are not nested within each other or within another block.
    • Using the block picker, select all three blocks and use the context menu to "Create a pattern"
    • Delete all the blocks from the page or post.
    • Look for your registered pattern in the block inserter under My Patterns
    • Deploy the pattern onto the page.

    Result: The blocks will be reinserted, but the pattern UI elements are not present. including the name of the pattern, the pattern's movement locking status (allowed, not allowed), etc.

    Hope that helps to explain a little better?

  6. SteveRyan-ASU commented on Jul 24, 2026

    @SteveRyan-ASU
    Author

    Following up: I asked Codex to do an analysis of the WP source code looking at this issue and the behavior demonstrated. It came up with the conclusion that the process for attaching the pattern metadata to a pattern relied specifically on having a "parent" block for which it attaches. The process is necessarily skipped when that isn't present.

    My prompt also asked for a couple of possible solutions, one of which seems at least possible although probably risky/complex. (The second proposed solution would produce a block with zero visible output on the screen, which I think would be a first within the editor and may pose usability challenges in selecting something that wasn't actually "there" except in the block picker.)

    The entire text of the response follows here. 👍


    Summary Of Findings
    The wrapped pattern receives the fuller WP 7.0 pattern/content-only treatment because Gutenberg attaches metadata.patternName only when the parsed pattern has exactly one root block. A flat multi-root pattern is still inserted from the Patterns UI, but no inserted block becomes the single “section block” that the pattern editing UI and content-only logic rely on.

    This is not a synced-pattern issue. It is an unsynced-pattern section/editing-mode limitation.

    Code-Path Analysis
    Theme patterns are registered server-side without structural assumptions:

    The structural behavior appears in the editor parser:

    Insertion passes pattern metadata transiently:

    The section/content-only logic then depends on that durable marker:

    Root-Cause Explanation
    Clearly proven by code: a flat pattern has no single root block, so parsePattern() does not attach metadata.patternName anywhere. Without that metadata, no block becomes an unsynced pattern section. Without a section block, Gutenberg has no anchor for the “Edit pattern” UI, list-view pattern identity, section movement behavior, or content-only propagation.

    Inference: this looks like an implementation limitation of the current pattern/editing-mode architecture, not an intentional semantic distinction between flat and wrapped patterns. The WP 7.0 testing docs describe unsynced patterns as defaulting to content-only mode, including an explicit “multi-block patterns” testing area, so flat multi-root behavior appears at least under-specified and likely buggy relative to the user-facing feature goal.

    Proposed Design Options

    1. Attach pattern metadata to every root block.

    This is the smallest change, but it is not enough by itself. Each top-level block would become its own section, not one pattern instance. A flat Heading + Image + Paragraph pattern would appear as three independent sections, with repeated labels and no shared movement/editing boundary. To make this work well, Core would also need an instance ID plus sibling-range logic.

    1. Add a persisted pseudo-root / transparent section block.

    Parse multi-root patterns into something like:

    <!-- wp:core/pattern-instance {"metadata":{"patternName":"theme/foo","name":"Foo"}} -->
    ...original root blocks...
    <!-- /wp:core/pattern-instance -->

    The block would save/render only its inner blocks, producing no extra front-end HTML. This gives Gutenberg a real parent clientId, so existing section, editing-mode, list-view, selection, and movement logic can mostly keep working.

    1. Add a virtual editor-only pattern instance model.

    On insertion, store { instanceId, patternName, rootClientId, childClientIds } in block-editor state, then teach selectors/UI to treat the sibling range as a section. To persist across reloads, Core would still need serialized metadata on the root blocks or another recoverable marker.

    Recommended Solution
    Best path: introduce a transparent persisted pseudo-root block for unsynced pattern instances, or a general “section”/“pattern instance” block, with no wrapper HTML output.

    That matches the current architecture instead of fighting it. The existing code wants one clientId to represent the section. A pseudo-root supplies that anchor while preserving the user goal: no visible wrapper element in rendered HTML.

    I would avoid the “metadata on every root block” approach as the primary design. It is tempting, but it creates a distributed identity problem and forces many selectors to understand sibling groups.

    Implementation Plan

    1. Add or prototype a transparent core/pattern-instance block:

      • Supports InnerBlocks.
      • Has metadata.patternName, metadata.name, categories.
      • Saves/renders InnerBlocks.Content only, with no wrapping element.
    2. Update [parsePattern()](https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/store/utils.js#L32-L47):

      • Keep current behavior for one root block if backward compatibility is desired.
      • For blocks.length > 1, wrap parsed blocks in the transparent pattern-instance block.
    3. Ensure section detection recognizes the carrier:

      • Either via existing metadata.patternName, or explicitly by block name.
      • Verify isSectionBlockCandidate(), getParentSectionBlock(), and getDerivedBlockEditingModesForTree() work unchanged or with minimal changes.
    4. Add tests:

    Risks And Unknowns

    • Existing already-inserted flat patterns cannot be reliably migrated into pattern instances unless their origin is recoverable.
    • Adding serialized block comments changes post content shape, even if rendered HTML is unchanged.
    • A fully virtual pseudo-root would avoid comment serialization, but it is much more invasive because many editor systems assume selectable things are real blocks.
    • Needs careful testing with undo/redo, copy/paste, multi-select, block hooks, list view, and nested patterns.

    Suggested Next Steps
    For a proof of concept, I’d start with the transparent pseudo-root block. It is the most practical way to support flat patterns without visible wrapper HTML and with the least disruption to existing section/editing-mode code.

  7. carolinan commented on Jul 24, 2026

    @carolinan
    Contributor

    But this statement is simply not true. They are both 100% very valid patterns.
    Sometimes you only want the user to insert the correct image. Then adding a group around it is unnecessary.
    If the developer still wants to add a group, they can, but it is only creating extra elements for no reasons.

    One set of blocks was actually treated as a pattern and the other was not.

  8. SteveRyan-ASU commented on Jul 24, 2026

    @SteveRyan-ASU
    Author

    That's a fair point. There is value from both a content creator and a theme developer perspective to have patterns that are both flat and grouped. Both simple and complex.

    Another example:

    • We have a pattern or two in our library that mocks up an entire sample page from scratch, completed with a hero image, breadcrumbs, a two column layout and a couple of other typographic features.
    • The intended use of that pattern is subtractive. We tell our faculty/staff "here's everything you might possibly need, delete the stuff that doesn't make sense for your content."
    • Because that pattern does not have a single wrapping block, the pattern UI is never invoked upon selection and deployment to the page.
    • Which in this case is a good thing. The pattern UI here would introduces friction in that the user would have to "deactivate" the pattern before deleting unwanted objects from the layout. They would then have to decide if they wanted to "reactivate" the pattern when they were done.

    I suppose a better way to sum up what I'm investigating here is whether or not there should be a way for pattern authors to be able to decide for themselves which of their created patterns should be presented with the pattern UI and which ones should not.

    With that in mind, I think that the design option above that comes closest to providing this choice would be the second option above:

    Add a persisted pseudo-root / transparent section block. Parse multi-root patterns into something like [the pseudo code below]. The block would save/render only its inner blocks, producing no extra front-end HTML. This gives Gutenberg a real parent clientId, so existing section, editing-mode, list-view, selection, and movement logic can mostly keep working.

    <!-- wp:core/pattern-instance {"metadata":{"patternName":"theme/foo","name":"Foo"}} -->
    ...original root blocks...
    <!-- /wp:core/pattern-instance -->
    

    I think this might be new territory for the block editor in general - it would deliberately introduce a block with no output on the front end. But that abstraction would remove the requirement for the pattern UI to be invoked only when a single "parent" block is present in the group of blocks representing the pattern content.

  9. youknowriad commented on Oct 19, 2026

    @youknowriad
    Contributor

    Thanks for the detailed write-up and the test patterns, @SteveRyan-ASU. As @carolinan explained, neither pattern is synced: both are regular patterns. Only a pattern with a single root block gets the pattern name attached, so only that one shows the pattern editing UI. That is still the case on WordPress 7.1.2 with Gutenberg trunk (built 2026-10-16). Since we agree this isn't a bug, I'm closing this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    [Type] BugAn existing feature does not function as intended

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions