Skip to content

Conversation

@talldan
Copy link
Contributor

@talldan talldan commented Oct 17, 2025

What?

I've noticed lately some cases where in contentOnly mode, certain block features are available that shouldn't be:

  • Movers, block insertion and block removal being allowed in synced patterns
  • Paragraphs being insertable/removable when at the root of an unsynced pattern (with the unsynced contentOnly patterns experiment active)
  • Movers available for paragraphs, list items and possibly other blocks inside templateLock: "contentOnly" groups. I think the expectation right now is that this shouldn't be possible, but I might need confirmation on that.

This PR should fix these issues, but still maintain the desired behavior from #71232

How?

Adjusts some logic in the relevant selectors. I've left some PR comments about the exact changes.

Testing Instructions

Synced patterns

  1. Create a synced pattern with the following markup:
<!-- wp:heading {"metadata":{"name":"Title","bindings":{"__default":{"source":"core/pattern-overrides"}}}} --> <h2 class="wp-block-heading">test</h2> <!-- /wp:heading --> <!-- wp:paragraph {"metadata":{"name":"Body text","bindings":{"__default":{"source":"core/pattern-overrides"}}}} --> <p>test</p> <!-- /wp:paragraph --> <!-- wp:image {"metadata":{"name":"Image","bindings":{"__default":{"source":"core/pattern-overrides"}}}} --> <figure class="wp-block-image"><img alt=""/><figcaption class="wp-element-caption"></figcaption></figure> <!-- /wp:image --> <!-- wp:buttons --> <div class="wp-block-buttons"><!-- wp:button {"metadata":{"name":"CTA","bindings":{"__default":{"source":"core/pattern-overrides"}}}} --> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="https://bbc.com">test</a></div> <!-- /wp:button --> <!-- wp:button {"metadata":{"name":"test","bindings":{"__default":{"source":"core/pattern-overrides"}}}} --> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button">test 2</a></div> <!-- /wp:button --></div> <!-- /wp:buttons --> <!-- wp:verse --> <pre class="wp-block-verse">verse text here</pre> <!-- /wp:verse -->
  1. Insert an instance of the pattern in a post
  2. Note that in trunk for the heading, paragraph, image you can Add before/after, Duplicate, and Delete, which should not be possible. In this branch it's fixed.
  3. In trunk you can also drag the paragraph to a new position, but that's no longer possible in this PR.

Unsynced patterns

(test with the contentOnly unsynced patterns experiment active).

  1. Create an unsynced pattern with the following markup:
<!-- wp:group {"metadata":{"patternName":"core/block/124","name":"test2"},"className":"is-style-section-2","layout":{"type":"constrained"}} --> <div class="wp-block-group is-style-section-2"><!-- wp:paragraph --> <p>test</p> <!-- /wp:paragraph --> <!-- wp:group {"layout":{"type":"constrained"}} --> <div class="wp-block-group"><!-- wp:paragraph --> <p>test</p> <!-- /wp:paragraph --></div> <!-- /wp:group --> <!-- wp:list --> <ul class="wp-block-list"><!-- wp:list-item --> <li>1</li> <!-- /wp:list-item --> <!-- wp:list-item --> <li>test<!-- wp:list --> <ul class="wp-block-list"><!-- wp:list-item --> <li>2</li> <!-- /wp:list-item --> <!-- wp:list-item --> <li>3</li> <!-- /wp:list-item --></ul> <!-- /wp:list --></li> <!-- /wp:list-item --></ul> <!-- /wp:list --> <!-- wp:group {"layout":{"type":"constrained"}} --> <div class="wp-block-group"><!-- wp:buttons --> <div class="wp-block-buttons"><!-- wp:button --> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button">test</a></div> <!-- /wp:button --> <!-- wp:button --> <div class="wp-block-button"><a class="wp-block-button__link wp-element-button">test</a></div> <!-- /wp:button --></div> <!-- /wp:buttons --></div> <!-- /wp:group --></div> <!-- /wp:group -->
  1. Insert an instance of the unsynced pattern
  2. Note that in trunk the paragraphs can be added/removed/duplicated etc. In this PR they cannot.
  3. Test that list items and buttons can still be inserted and removed.

templateLock: contentOnly

  1. Insert the following block markup:
<!-- wp:group {"templateLock":"contentOnly","layout":{"type":"constrained"}} --> <div class="wp-block-group"><!-- wp:paragraph --> <p>Locked block a</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>Locked block b</p> <!-- /wp:paragraph --> <!-- wp:list --> <ul class="wp-block-list"><!-- wp:list-item --> <li>1</li> <!-- /wp:list-item --> <!-- wp:list-item --> <li>2</li> <!-- /wp:list-item --></ul> <!-- /wp:list --></div> <!-- /wp:group -->
  1. Check that all the blocks cannot be added/removed or moved. (I think that's how it's supposed to work 😅 )

Also worth testing

  • 'Show Template' mode, blocks within Post content should be freely insertable, removable etc. Blocks that are part of the template shouldn't be.

Screenshots or screencast

Content Only Template Lock

Before

Screenshot 2025-10-20 at 12 39 07 pm

After

Screenshot 2025-10-20 at 12 39 27 pm

Synced Patterns

Before

Screenshot 2025-10-20 at 12 41 46 pm

After

Screenshot 2025-10-20 at 12 41 25 pm

Unsynced Patterns

Before

Screenshot 2025-10-20 at 12 48 38 pm

After

Screenshot 2025-10-20 at 12 48 18 pm
@talldan talldan self-assigned this Oct 17, 2025
@talldan talldan requested a review from ellatrix as a code owner October 17, 2025 08:21
@talldan talldan added [Type] Bug An existing feature does not function as intended [Feature] Patterns A collection of blocks that can be synced (previously reusable blocks) or unsynced labels Oct 17, 2025
if (
blockEditingMode === 'contentOnly' &&
! isContainerInsertableToInWriteMode( state, blockName, rootClientId )
( isParentSectionBlock || blockEditingMode === 'contentOnly' ) &&
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the parent is a 'section' it usually has a blockEditingMode of default (so that you can move, insert, remove the section), but I think that results in skipping the isContainerInsertableToInContentOnlyMode logic, so I've added an extra check for isParentSectionBlock here..

Copy link
Contributor

Choose a reason for hiding this comment

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

Should we maybe change isContainerInsertableToInContentOnlyMode to remove the logic that allows inserting if a block is a section root? That made sense in write mode so blocks could be added to empty templates, but with the patterns approach we probably don't need to do that anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let me try it. I guess zoomed out would be the only concern, as I think it still uses section roots. Though I don't think it uses contentOnly at all, so I don't think it should be a problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's still needed for zoomed out based on my testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

We could maybe look at removing it when we get to updating the zoom out logic (i.e. as part of #71807).

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, we should remove it when we simplify zoom out.

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

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: talldan <talldanwp@git.wordpress.org> Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org> Co-authored-by: ramonjd <ramonopoly@git.wordpress.org> Co-authored-by: andrewserong <andrewserong@git.wordpress.org> Co-authored-by: scruffian <scruffian@git.wordpress.org> 

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

}

const blockEditingMode = getBlockEditingMode( state, rootClientId );
const blockEditingMode = getBlockEditingMode( state, clientId );
Copy link
Contributor Author

@talldan talldan Oct 17, 2025

Choose a reason for hiding this comment

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

It didn't make sense to me that we check the root here, so I've changed it to check the clientId being removed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Iirc that's intended to match the logic for block insertion in canInsertBlockTypeUnmemoized (this line). I wanted to ensure that if a block can be inserted it can always be deleted (in some cases the "delete" option was unavailable from the options menu even when you could "duplicate" or "add after" etc..)

Copy link
Contributor

Choose a reason for hiding this comment

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

A quick test of blocks like List, Buttons and Quote shows it's still possible to delete blocks inside them, so maybe it doesn't make that much of a difference.

Copy link
Contributor Author

@talldan talldan Oct 21, 2025

Choose a reason for hiding this comment

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

That's true. Maybe I should change it back to see if it causes any issues.

I do agree with the idea of making the logic similar in both selectors, but the issue I'm wondering about is the way blockEditingMode works. Usually it's possible to have a contentOnly parent block with a default (enabled) inner blocks. That's how the Post Content block works when the 'Show Template option is used.

I guess the difference is that after your recent changes, the new logic is that blockEditingMode: contentOnly now works differently for container blocks that have the content role and it enforces that the children must also have a content role and be contentOnly. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the selectors to have matching logic, and it looks like everything still works, so that's good 😄

I think we could consider moving more of the logic related to insertion, moving, deletion for blocks within sections into a single function, perhaps repurpose isContainerInsertableToInContentOnlyMode, it seems like an easy way to keep the code always consistent across the three selectors.

I'll leave it till later on though.

! isContainerInsertableToInContentOnlyMode(
state,
getBlockName( state, rootClientId ),
getBlockName( state, clientId ),
Copy link
Contributor Author

@talldan talldan Oct 17, 2025

Choose a reason for hiding this comment

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

This line looks to be a typo, because it results in isContainerInsertableToInContentOnlyMode checking whether the root block is a content block twice.

Copy link
Member

Choose a reason for hiding this comment

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

Just checking if user-created unsynced patterns are supposed to be included? I can still delete child blocks.

I enabled the content only experiment, created an unsynced pattern, then inserted it into a post via the inserter.

The first pattern is mine, the second is a theme pattern inserted from the patterns inserter.

Kapture.2025-10-21.at.11.56.38.mp4
Comment on lines 1925 to 1935
const blockEditingMode = getBlockEditingMode( state, clientId );
if (
blockEditingMode === 'contentOnly' &&
! isContainerInsertableToInContentOnlyMode(
state,
getBlockName( state, clientId ),
rootClientId
)
) {
return false;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

To fix movers, also replicate the isContainerInsertableToInContentOnlyMode here in the canMoveBlock selector.

@talldan talldan marked this pull request as draft October 17, 2025 08:28
@talldan
Copy link
Contributor Author

talldan commented Oct 17, 2025

I should write some tests, and I probably need to update some of the existing tests, I'll keep it a draft until I've done that.

edit: all the existing tests passed 🤷

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

Size Change: +63 B (0%)

Total Size: 2.19 MB

Filename Size Change
build/scripts/block-editor/index.min.js 296 kB +60 B (+0.02%)
build/scripts/block-library/index.min.js 266 kB +3 B (0%)
ℹ️ View Unchanged
Filename Size
build/modules/a11y/index.min.js 355 B
build/modules/block-editor/utils/fit-text-frontend.min.js 551 B
build/modules/block-library/accordion/view.min.js 520 B
build/modules/block-library/file/view.min.js 346 B
build/modules/block-library/form/view.min.js 528 B
build/modules/block-library/image/view.min.js 1.64 kB
build/modules/block-library/navigation/view.min.js 1.03 kB
build/modules/block-library/query/view.min.js 518 B
build/modules/block-library/search/view.min.js 498 B
build/modules/interactivity-router/full-page.min.js 451 B
build/modules/interactivity-router/index.min.js 11.6 kB
build/modules/interactivity/index.min.js 14.9 kB
build/modules/latex-to-mathml/index.min.js 56.5 kB
build/modules/latex-to-mathml/loader.min.js 131 B
build/scripts/a11y/index.min.js 1.06 kB
build/scripts/annotations/index.min.js 2.38 kB
build/scripts/api-fetch/index.min.js 2.83 kB
build/scripts/autop/index.min.js 2.18 kB
build/scripts/blob/index.min.js 631 B
build/scripts/block-directory/index.min.js 8.04 kB
build/scripts/block-serialization-default-parser/index.min.js 1.16 kB
build/scripts/block-serialization-spec-parser/index.min.js 3.08 kB
build/scripts/blocks/index.min.js 56.7 kB
build/scripts/commands/index.min.js 17.4 kB
build/scripts/components/index.min.js 271 kB
build/scripts/compose/index.min.js 13.8 kB
build/scripts/core-commands/index.min.js 4.1 kB
build/scripts/core-data/index.min.js 85.1 kB
build/scripts/customize-widgets/index.min.js 12.3 kB
build/scripts/data-controls/index.min.js 793 B
build/scripts/data/index.min.js 9.61 kB
build/scripts/date/index.min.js 23.6 kB
build/scripts/deprecated/index.min.js 755 B
build/scripts/dom-ready/index.min.js 476 B
build/scripts/dom/index.min.js 4.91 kB
build/scripts/edit-post/index.min.js 16.8 kB
build/scripts/edit-site/index.min.js 269 kB
build/scripts/edit-widgets/index.min.js 20 kB
build/scripts/editor/index.min.js 138 kB
build/scripts/element/index.min.js 5.19 kB
build/scripts/escape-html/index.min.js 586 B
build/scripts/format-library/index.min.js 10.6 kB
build/scripts/hooks/index.min.js 1.83 kB
build/scripts/html-entities/index.min.js 494 B
build/scripts/i18n/index.min.js 2.46 kB
build/scripts/is-shallow-equal/index.min.js 568 B
build/scripts/keyboard-shortcuts/index.min.js 1.57 kB
build/scripts/keycodes/index.min.js 1.53 kB
build/scripts/latex-to-mathml/index.min.js 56.7 kB
build/scripts/list-reusable-blocks/index.min.js 2.44 kB
build/scripts/media-utils/index.min.js 3.96 kB
build/scripts/notices/index.min.js 1.11 kB
build/scripts/nux/index.min.js 1.88 kB
build/scripts/patterns/index.min.js 8.62 kB
build/scripts/plugins/index.min.js 2.14 kB
build/scripts/preferences-persistence/index.min.js 2.15 kB
build/scripts/preferences/index.min.js 3.3 kB
build/scripts/primitives/index.min.js 1.01 kB
build/scripts/priority-queue/index.min.js 1.61 kB
build/scripts/private-apis/index.min.js 1.04 kB
build/scripts/react-i18n/index.min.js 832 B
build/scripts/react-refresh-entry/index.min.js 9.44 kB
build/scripts/react-refresh-runtime/index.min.js 3.59 kB
build/scripts/redux-routine/index.min.js 3.36 kB
build/scripts/reusable-blocks/index.min.js 2.92 kB
build/scripts/rich-text/index.min.js 12.9 kB
build/scripts/router/index.min.js 5.96 kB
build/scripts/server-side-render/index.min.js 1.9 kB
build/scripts/shortcode/index.min.js 1.58 kB
build/scripts/style-engine/index.min.js 2.31 kB
build/scripts/theme/index.min.js 28.4 kB
build/scripts/token-list/index.min.js 740 B
build/scripts/undo-manager/index.min.js 915 B
build/scripts/url/index.min.js 3.98 kB
build/scripts/vendors/react-dom.min.js 43 kB
build/scripts/vendors/react-jsx-runtime.min.js 691 B
build/scripts/vendors/react.min.js 4.27 kB
build/scripts/viewport/index.min.js 1.22 kB
build/scripts/warning/index.min.js 454 B
build/scripts/widgets/index.min.js 7.83 kB
build/scripts/wordcount/index.min.js 1.04 kB
build/styles/block-directory/style-rtl.css 1.05 kB
build/styles/block-directory/style.css 1.05 kB
build/styles/block-editor/content-rtl.css 4.81 kB
build/styles/block-editor/content.css 4.8 kB
build/styles/block-editor/default-editor-styles-rtl.css 224 B
build/styles/block-editor/default-editor-styles.css 224 B
build/styles/block-editor/style-rtl.css 16.2 kB
build/styles/block-editor/style.css 16.2 kB
build/styles/block-library/accordion-heading/style-rtl.css 340 B
build/styles/block-library/accordion-heading/style.css 340 B
build/styles/block-library/accordion-item/style-rtl.css 213 B
build/styles/block-library/accordion-item/style.css 213 B
build/styles/block-library/accordion-panel/style-rtl.css 99 B
build/styles/block-library/accordion-panel/style.css 99 B
build/styles/block-library/archives/editor-rtl.css 61 B
build/styles/block-library/archives/editor.css 61 B
build/styles/block-library/archives/style-rtl.css 90 B
build/styles/block-library/archives/style.css 90 B
build/styles/block-library/audio/editor-rtl.css 149 B
build/styles/block-library/audio/editor.css 151 B
build/styles/block-library/audio/style-rtl.css 132 B
build/styles/block-library/audio/style.css 132 B
build/styles/block-library/audio/theme-rtl.css 134 B
build/styles/block-library/audio/theme.css 134 B
build/styles/block-library/avatar/editor-rtl.css 115 B
build/styles/block-library/avatar/editor.css 115 B
build/styles/block-library/avatar/style-rtl.css 104 B
build/styles/block-library/avatar/style.css 104 B
build/styles/block-library/breadcrumbs/style-rtl.css 203 B
build/styles/block-library/breadcrumbs/style.css 203 B
build/styles/block-library/button/editor-rtl.css 265 B
build/styles/block-library/button/editor.css 265 B
build/styles/block-library/button/style-rtl.css 554 B
build/styles/block-library/button/style.css 554 B
build/styles/block-library/buttons/editor-rtl.css 291 B
build/styles/block-library/buttons/editor.css 291 B
build/styles/block-library/buttons/style-rtl.css 349 B
build/styles/block-library/buttons/style.css 349 B
build/styles/block-library/calendar/style-rtl.css 239 B
build/styles/block-library/calendar/style.css 239 B
build/styles/block-library/categories/editor-rtl.css 132 B
build/styles/block-library/categories/editor.css 131 B
build/styles/block-library/categories/style-rtl.css 152 B
build/styles/block-library/categories/style.css 152 B
build/styles/block-library/classic-rtl.css 179 B
build/styles/block-library/classic.css 179 B
build/styles/block-library/code/editor-rtl.css 53 B
build/styles/block-library/code/editor.css 53 B
build/styles/block-library/code/style-rtl.css 139 B
build/styles/block-library/code/style.css 139 B
build/styles/block-library/code/theme-rtl.css 122 B
build/styles/block-library/code/theme.css 122 B
build/styles/block-library/columns/editor-rtl.css 108 B
build/styles/block-library/columns/editor.css 108 B
build/styles/block-library/columns/style-rtl.css 421 B
build/styles/block-library/columns/style.css 421 B
build/styles/block-library/comment-author-avatar/editor-rtl.css 124 B
build/styles/block-library/comment-author-avatar/editor.css 124 B
build/styles/block-library/comment-author-name/style-rtl.css 72 B
build/styles/block-library/comment-author-name/style.css 72 B
build/styles/block-library/comment-content/style-rtl.css 120 B
build/styles/block-library/comment-content/style.css 120 B
build/styles/block-library/comment-date/style-rtl.css 65 B
build/styles/block-library/comment-date/style.css 65 B
build/styles/block-library/comment-edit-link/style-rtl.css 70 B
build/styles/block-library/comment-edit-link/style.css 70 B
build/styles/block-library/comment-reply-link/style-rtl.css 71 B
build/styles/block-library/comment-reply-link/style.css 71 B
build/styles/block-library/comment-template/style-rtl.css 191 B
build/styles/block-library/comment-template/style.css 191 B
build/styles/block-library/comments-pagination-numbers/editor-rtl.css 122 B
build/styles/block-library/comments-pagination-numbers/editor.css 121 B
build/styles/block-library/comments-pagination/editor-rtl.css 168 B
build/styles/block-library/comments-pagination/editor.css 168 B
build/styles/block-library/comments-pagination/style-rtl.css 201 B
build/styles/block-library/comments-pagination/style.css 201 B
build/styles/block-library/comments-title/editor-rtl.css 75 B
build/styles/block-library/comments-title/editor.css 75 B
build/styles/block-library/comments/editor-rtl.css 842 B
build/styles/block-library/comments/editor.css 842 B
build/styles/block-library/comments/style-rtl.css 637 B
build/styles/block-library/comments/style.css 637 B
build/styles/block-library/common-rtl.css 1.11 kB
build/styles/block-library/common.css 1.11 kB
build/styles/block-library/cover/editor-rtl.css 631 B
build/styles/block-library/cover/editor.css 631 B
build/styles/block-library/cover/style-rtl.css 1.7 kB
build/styles/block-library/cover/style.css 1.69 kB
build/styles/block-library/details/editor-rtl.css 65 B
build/styles/block-library/details/editor.css 65 B
build/styles/block-library/details/style-rtl.css 86 B
build/styles/block-library/details/style.css 86 B
build/styles/block-library/editor-elements-rtl.css 75 B
build/styles/block-library/editor-elements.css 75 B
build/styles/block-library/editor-rtl.css 11.6 kB
build/styles/block-library/editor.css 11.6 kB
build/styles/block-library/elements-rtl.css 54 B
build/styles/block-library/elements.css 54 B
build/styles/block-library/embed/editor-rtl.css 331 B
build/styles/block-library/embed/editor.css 331 B
build/styles/block-library/embed/style-rtl.css 419 B
build/styles/block-library/embed/style.css 419 B
build/styles/block-library/embed/theme-rtl.css 133 B
build/styles/block-library/embed/theme.css 133 B
build/styles/block-library/file/editor-rtl.css 324 B
build/styles/block-library/file/editor.css 324 B
build/styles/block-library/file/style-rtl.css 278 B
build/styles/block-library/file/style.css 278 B
build/styles/block-library/footnotes/style-rtl.css 198 B
build/styles/block-library/footnotes/style.css 197 B
build/styles/block-library/form-input/editor-rtl.css 229 B
build/styles/block-library/form-input/editor.css 229 B
build/styles/block-library/form-input/style-rtl.css 366 B
build/styles/block-library/form-input/style.css 366 B
build/styles/block-library/form-submission-notification/editor-rtl.css 344 B
build/styles/block-library/form-submission-notification/editor.css 341 B
build/styles/block-library/form-submit-button/style-rtl.css 69 B
build/styles/block-library/form-submit-button/style.css 69 B
build/styles/block-library/freeform/editor-rtl.css 2.59 kB
build/styles/block-library/freeform/editor.css 2.59 kB
build/styles/block-library/gallery/editor-rtl.css 615 B
build/styles/block-library/gallery/editor.css 616 B
build/styles/block-library/gallery/style-rtl.css 1.84 kB
build/styles/block-library/gallery/style.css 1.84 kB
build/styles/block-library/gallery/theme-rtl.css 108 B
build/styles/block-library/gallery/theme.css 108 B
build/styles/block-library/group/editor-rtl.css 335 B
build/styles/block-library/group/editor.css 335 B
build/styles/block-library/group/style-rtl.css 103 B
build/styles/block-library/group/style.css 103 B
build/styles/block-library/group/theme-rtl.css 79 B
build/styles/block-library/group/theme.css 79 B
build/styles/block-library/heading/style-rtl.css 188 B
build/styles/block-library/heading/style.css 188 B
build/styles/block-library/html/editor-rtl.css 357 B
build/styles/block-library/html/editor.css 358 B
build/styles/block-library/image/editor-rtl.css 763 B
build/styles/block-library/image/editor.css 763 B
build/styles/block-library/image/style-rtl.css 1.6 kB
build/styles/block-library/image/style.css 1.59 kB
build/styles/block-library/image/theme-rtl.css 137 B
build/styles/block-library/image/theme.css 137 B
build/styles/block-library/latest-comments/style-rtl.css 355 B
build/styles/block-library/latest-comments/style.css 354 B
build/styles/block-library/latest-posts/editor-rtl.css 139 B
build/styles/block-library/latest-posts/editor.css 138 B
build/styles/block-library/latest-posts/style-rtl.css 520 B
build/styles/block-library/latest-posts/style.css 520 B
build/styles/block-library/list/style-rtl.css 107 B
build/styles/block-library/list/style.css 107 B
build/styles/block-library/loginout/style-rtl.css 61 B
build/styles/block-library/loginout/style.css 61 B
build/styles/block-library/media-text/editor-rtl.css 321 B
build/styles/block-library/media-text/editor.css 320 B
build/styles/block-library/media-text/style-rtl.css 543 B
build/styles/block-library/media-text/style.css 542 B
build/styles/block-library/more/editor-rtl.css 393 B
build/styles/block-library/more/editor.css 393 B
build/styles/block-library/navigation-link/editor-rtl.css 626 B
build/styles/block-library/navigation-link/editor.css 628 B
build/styles/block-library/navigation-link/style-rtl.css 190 B
build/styles/block-library/navigation-link/style.css 188 B
build/styles/block-library/navigation-submenu/editor-rtl.css 295 B
build/styles/block-library/navigation-submenu/editor.css 294 B
build/styles/block-library/navigation/editor-rtl.css 2.24 kB
build/styles/block-library/navigation/editor.css 2.24 kB
build/styles/block-library/navigation/style-rtl.css 2.27 kB
build/styles/block-library/navigation/style.css 2.25 kB
build/styles/block-library/nextpage/editor-rtl.css 392 B
build/styles/block-library/nextpage/editor.css 392 B
build/styles/block-library/page-list/editor-rtl.css 356 B
build/styles/block-library/page-list/editor.css 356 B
build/styles/block-library/page-list/style-rtl.css 192 B
build/styles/block-library/page-list/style.css 192 B
build/styles/block-library/paragraph/editor-rtl.css 251 B
build/styles/block-library/paragraph/editor.css 251 B
build/styles/block-library/paragraph/style-rtl.css 341 B
build/styles/block-library/paragraph/style.css 340 B
build/styles/block-library/post-author-biography/style-rtl.css 74 B
build/styles/block-library/post-author-biography/style.css 74 B
build/styles/block-library/post-author-name/style-rtl.css 69 B
build/styles/block-library/post-author-name/style.css 69 B
build/styles/block-library/post-author/style-rtl.css 188 B
build/styles/block-library/post-author/style.css 189 B
build/styles/block-library/post-comments-count/style-rtl.css 72 B
build/styles/block-library/post-comments-count/style.css 72 B
build/styles/block-library/post-comments-form/editor-rtl.css 96 B
build/styles/block-library/post-comments-form/editor.css 96 B
build/styles/block-library/post-comments-form/style-rtl.css 525 B
build/styles/block-library/post-comments-form/style.css 525 B
build/styles/block-library/post-comments-link/style-rtl.css 71 B
build/styles/block-library/post-comments-link/style.css 71 B
build/styles/block-library/post-content/style-rtl.css 61 B
build/styles/block-library/post-content/style.css 61 B
build/styles/block-library/post-date/style-rtl.css 62 B
build/styles/block-library/post-date/style.css 62 B
build/styles/block-library/post-excerpt/editor-rtl.css 71 B
build/styles/block-library/post-excerpt/editor.css 71 B
build/styles/block-library/post-excerpt/style-rtl.css 155 B
build/styles/block-library/post-excerpt/style.css 155 B
build/styles/block-library/post-featured-image/editor-rtl.css 719 B
build/styles/block-library/post-featured-image/editor.css 717 B
build/styles/block-library/post-featured-image/style-rtl.css 347 B
build/styles/block-library/post-featured-image/style.css 347 B
build/styles/block-library/post-navigation-link/style-rtl.css 215 B
build/styles/block-library/post-navigation-link/style.css 214 B
build/styles/block-library/post-template/style-rtl.css 414 B
build/styles/block-library/post-template/style.css 414 B
build/styles/block-library/post-terms/style-rtl.css 96 B
build/styles/block-library/post-terms/style.css 96 B
build/styles/block-library/post-time-to-read/style-rtl.css 70 B
build/styles/block-library/post-time-to-read/style.css 70 B
build/styles/block-library/post-title/style-rtl.css 162 B
build/styles/block-library/post-title/style.css 162 B
build/styles/block-library/preformatted/style-rtl.css 125 B
build/styles/block-library/preformatted/style.css 125 B
build/styles/block-library/pullquote/editor-rtl.css 133 B
build/styles/block-library/pullquote/editor.css 133 B
build/styles/block-library/pullquote/style-rtl.css 365 B
build/styles/block-library/pullquote/style.css 365 B
build/styles/block-library/pullquote/theme-rtl.css 176 B
build/styles/block-library/pullquote/theme.css 176 B
build/styles/block-library/query-pagination-numbers/editor-rtl.css 121 B
build/styles/block-library/query-pagination-numbers/editor.css 118 B
build/styles/block-library/query-pagination/editor-rtl.css 154 B
build/styles/block-library/query-pagination/editor.css 154 B
build/styles/block-library/query-pagination/style-rtl.css 237 B
build/styles/block-library/query-pagination/style.css 237 B
build/styles/block-library/query-title/style-rtl.css 64 B
build/styles/block-library/query-title/style.css 64 B
build/styles/block-library/query-total/style-rtl.css 64 B
build/styles/block-library/query-total/style.css 64 B
build/styles/block-library/query/editor-rtl.css 438 B
build/styles/block-library/query/editor.css 438 B
build/styles/block-library/quote/style-rtl.css 238 B
build/styles/block-library/quote/style.css 238 B
build/styles/block-library/quote/theme-rtl.css 233 B
build/styles/block-library/quote/theme.css 236 B
build/styles/block-library/read-more/style-rtl.css 131 B
build/styles/block-library/read-more/style.css 131 B
build/styles/block-library/reset-rtl.css 472 B
build/styles/block-library/reset.css 472 B
build/styles/block-library/rss/editor-rtl.css 126 B
build/styles/block-library/rss/editor.css 126 B
build/styles/block-library/rss/style-rtl.css 284 B
build/styles/block-library/rss/style.css 283 B
build/styles/block-library/search/editor-rtl.css 199 B
build/styles/block-library/search/editor.css 199 B
build/styles/block-library/search/style-rtl.css 665 B
build/styles/block-library/search/style.css 666 B
build/styles/block-library/search/theme-rtl.css 113 B
build/styles/block-library/search/theme.css 113 B
build/styles/block-library/separator/editor-rtl.css 100 B
build/styles/block-library/separator/editor.css 100 B
build/styles/block-library/separator/style-rtl.css 248 B
build/styles/block-library/separator/style.css 248 B
build/styles/block-library/separator/theme-rtl.css 195 B
build/styles/block-library/separator/theme.css 195 B
build/styles/block-library/shortcode/editor-rtl.css 286 B
build/styles/block-library/shortcode/editor.css 286 B
build/styles/block-library/site-logo/editor-rtl.css 773 B
build/styles/block-library/site-logo/editor.css 770 B
build/styles/block-library/site-logo/style-rtl.css 218 B
build/styles/block-library/site-logo/style.css 218 B
build/styles/block-library/site-tagline/editor-rtl.css 87 B
build/styles/block-library/site-tagline/editor.css 87 B
build/styles/block-library/site-tagline/style-rtl.css 65 B
build/styles/block-library/site-tagline/style.css 65 B
build/styles/block-library/site-title/editor-rtl.css 85 B
build/styles/block-library/site-title/editor.css 85 B
build/styles/block-library/site-title/style-rtl.css 143 B
build/styles/block-library/site-title/style.css 143 B
build/styles/block-library/social-link/editor-rtl.css 314 B
build/styles/block-library/social-link/editor.css 314 B
build/styles/block-library/social-links/editor-rtl.css 339 B
build/styles/block-library/social-links/editor.css 338 B
build/styles/block-library/social-links/style-rtl.css 1.51 kB
build/styles/block-library/social-links/style.css 1.51 kB
build/styles/block-library/spacer/editor-rtl.css 346 B
build/styles/block-library/spacer/editor.css 346 B
build/styles/block-library/spacer/style-rtl.css 48 B
build/styles/block-library/spacer/style.css 48 B
build/styles/block-library/style-rtl.css 15.6 kB
build/styles/block-library/style.css 15.6 kB
build/styles/block-library/table-of-contents/style-rtl.css 83 B
build/styles/block-library/table-of-contents/style.css 83 B
build/styles/block-library/table/editor-rtl.css 394 B
build/styles/block-library/table/editor.css 394 B
build/styles/block-library/table/style-rtl.css 641 B
build/styles/block-library/table/style.css 640 B
build/styles/block-library/table/theme-rtl.css 152 B
build/styles/block-library/table/theme.css 152 B
build/styles/block-library/tag-cloud/editor-rtl.css 92 B
build/styles/block-library/tag-cloud/editor.css 92 B
build/styles/block-library/tag-cloud/style-rtl.css 248 B
build/styles/block-library/tag-cloud/style.css 248 B
build/styles/block-library/template-part/editor-rtl.css 368 B
build/styles/block-library/template-part/editor.css 368 B
build/styles/block-library/template-part/theme-rtl.css 113 B
build/styles/block-library/template-part/theme.css 113 B
build/styles/block-library/term-count/style-rtl.css 63 B
build/styles/block-library/term-count/style.css 63 B
build/styles/block-library/term-description/style-rtl.css 126 B
build/styles/block-library/term-description/style.css 126 B
build/styles/block-library/term-name/style-rtl.css 62 B
build/styles/block-library/term-name/style.css 62 B
build/styles/block-library/term-template/editor-rtl.css 225 B
build/styles/block-library/term-template/editor.css 225 B
build/styles/block-library/term-template/style-rtl.css 114 B
build/styles/block-library/term-template/style.css 114 B
build/styles/block-library/text-columns/editor-rtl.css 95 B
build/styles/block-library/text-columns/editor.css 95 B
build/styles/block-library/text-columns/style-rtl.css 165 B
build/styles/block-library/text-columns/style.css 165 B
build/styles/block-library/theme-rtl.css 715 B
build/styles/block-library/theme.css 719 B
build/styles/block-library/verse/style-rtl.css 98 B
build/styles/block-library/verse/style.css 98 B
build/styles/block-library/video/editor-rtl.css 415 B
build/styles/block-library/video/editor.css 416 B
build/styles/block-library/video/style-rtl.css 202 B
build/styles/block-library/video/style.css 202 B
build/styles/block-library/video/theme-rtl.css 134 B
build/styles/block-library/video/theme.css 134 B
build/styles/commands/style-rtl.css 999 B
build/styles/commands/style.css 1 kB
build/styles/components/style-rtl.css 14 kB
build/styles/components/style.css 14 kB
build/styles/customize-widgets/style-rtl.css 1.44 kB
build/styles/customize-widgets/style.css 1.44 kB
build/styles/edit-post/classic-rtl.css 426 B
build/styles/edit-post/classic.css 427 B
build/styles/edit-post/style-rtl.css 3.33 kB
build/styles/edit-post/style.css 3.33 kB
build/styles/edit-site/posts-rtl.css 9.95 kB
build/styles/edit-site/posts.css 9.95 kB
build/styles/edit-site/style-rtl.css 15.9 kB
build/styles/edit-site/style.css 15.9 kB
build/styles/edit-widgets/style-rtl.css 4.59 kB
build/styles/edit-widgets/style.css 4.59 kB
build/styles/editor/style-rtl.css 9.94 kB
build/styles/editor/style.css 9.94 kB
build/styles/format-library/style-rtl.css 308 B
build/styles/format-library/style.css 308 B
build/styles/list-reusable-blocks/style-rtl.css 1.02 kB
build/styles/list-reusable-blocks/style.css 1.02 kB
build/styles/nux/style-rtl.css 622 B
build/styles/nux/style.css 618 B
build/styles/patterns/style-rtl.css 703 B
build/styles/patterns/style.css 703 B
build/styles/preferences/style-rtl.css 415 B
build/styles/preferences/style.css 415 B
build/styles/reusable-blocks/style-rtl.css 275 B
build/styles/reusable-blocks/style.css 275 B
build/styles/theme/style.css 52 B
build/styles/widgets/style-rtl.css 1.17 kB
build/styles/widgets/style.css 1.18 kB

compressed-size-action

@github-actions
Copy link

github-actions bot commented Oct 17, 2025

Flaky tests detected in 63cec0b.
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/18738363405
📝 Reported issues:

@talldan talldan marked this pull request as ready for review October 20, 2025 04:50
@talldan talldan added the Backport to WP 6.9 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Oct 20, 2025
@github-project-automation github-project-automation bot moved this to 🔎 Needs Review in WordPress 6.9 Editor Tasks Oct 20, 2025
Copy link
Member

@ramonjd ramonjd 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 working according to the PR test instructions for me, thanks.

Tested with the content only experiment on and off.

The only thing I noticed was that user-created unsynced patterns were still draggable/deletable. Is that intentional?

! isContainerInsertableToInContentOnlyMode(
state,
getBlockName( state, rootClientId ),
getBlockName( state, clientId ),
Copy link
Member

Choose a reason for hiding this comment

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

Just checking if user-created unsynced patterns are supposed to be included? I can still delete child blocks.

I enabled the content only experiment, created an unsynced pattern, then inserted it into a post via the inserter.

The first pattern is mine, the second is a theme pattern inserted from the patterns inserter.

Kapture.2025-10-21.at.11.56.38.mp4
@talldan
Copy link
Contributor Author

talldan commented Oct 21, 2025

The only thing I noticed was that user-created unsynced patterns were still draggable/deletable. Is that intentional?

The whole pattern should be draggable/deletable yep. For the blocks inside, some should be draggable (List Items, Buttons).

Just checking if user-created unsynced patterns are supposed to be included? I can still delete child blocks.

Hmm, yeah, that's a bug. Seems to happen when the blocks are at the root level. I thought I'd solved that.

@talldan
Copy link
Contributor Author

talldan commented Oct 21, 2025

Hmm, yeah, that's a bug. Seems to happen when the blocks are at the root level. I thought I'd solved that.

Ok, so the bug happens when an unsynced pattern is first created, but if you reload the editor then it works again. Same if you insert an existing unsynced pattern. The issue is probably related to the selector dependencies, so hopefully an easy-ish fix.

@tellthemachines
Copy link
Contributor

Paragraphs being insertable/removable when at the root of an unsynced pattern

Should we not allow this to happen? Presumably places where text lives should be able to accommodate varying amounts of it? My main concern here is that pattern authors may resort to workarounds such as using an unstyled Quote container to allow adding multiple paragraphs 😅

@talldan
Copy link
Contributor Author

talldan commented Oct 21, 2025

Should we not allow this to happen? Presumably places where text lives should be able to accommodate varying amounts of it? My main concern here is that pattern authors may resort to workarounds such as using an unstyled Quote container to allow adding multiple paragraphs 😅

I don't think there should be any difference with how paragraphs work at the root of the pattern vs how they work in a group within a pattern.

For the contentOnly experiment there's visually no difference, so it makes no sense to a user that one option allows more paragraphs to be inserted while the other doesn't.

@talldan talldan force-pushed the fix/content-only-insertion-removal-and-moving branch from 321e63d to ed8bfd5 Compare October 21, 2025 08:13
Object.entries( {
block1: { name: 'core/test-block-ancestor' },
block2: { name: 'core/block' },
block2: { name: 'core/group' },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

core/block is a synced pattern, which is a section, so it wouldn't allow insertion, the selector now prevents it. The block in this test needed to be changed to a different container block, one that's not a section.

@talldan
Copy link
Contributor Author

talldan commented Oct 21, 2025

Just checking if user-created unsynced patterns are supposed to be included? I can still delete child blocks.

This should be fixed now, @ramonjd.

@ramonjd
Copy link
Member

ramonjd commented Oct 21, 2025

This should be fixed now, @ramonjd.

Thanks!

I just retested since 124b988 by creating an unsynced pattern in the editor.

I can delete blocks, but when they're inside a Cover or Media & Text block so I'm now wondering if it's block-specific.

Screenshot 2025-10-22 at 9 41 04 am Screenshot 2025-10-22 at 9 45 58 am

Here's my root block (Cover) HTML:

<!-- wp:cover {"overlayColor":"vivid-red","isUserOverlayColor":true,"metadata":{"patternName":"core/block/441","name":"unsynced 2"},"layout":{"type":"constrained"}} -->

Sorry, I ran out of time to debug further.

Everything else tests as expected. 🚀

Probably best to do follow ups if it's block-specific? If so then this PR LGTM.

@ramonjd
Copy link
Member

ramonjd commented Oct 21, 2025

I kicked off the E2E tests, but I think they are related. At least this one is:

Error: 2) [chromium] › test/e2e/specs/editor/plugins/post-type-locking.spec.js:170:3 › Post-type locking › template_lock insert › should allow blocks to be moved Retry #1 ─────────────────────────────────────────────────────────────────────────────────────── TimeoutError: locator.click: Timeout 10000ms exceeded. Call log: - waiting for locator('role=toolbar[name="Block tools"i]').locator('role=button[name="Move up"]') at ../../../packages/e2e-test-utils-playwright/src/editor/click-block-toolbar-button.ts:20 18 |	const button = blockToolbar.locator( `role=button[name="${ label }"]` ); 19 | > 20 |	await button.click(); 
Before After
Screenshot 2025-10-22 at 9 53 16 am Screenshot 2025-10-22 at 9 51 57 am
@talldan talldan requested a review from fabiankaegy as a code owner October 22, 2025 08:14
Copy link
Contributor

@andrewserong andrewserong 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 testing great for me, thanks for the thorough instructions!

I think it would make sense to be able to add new paragraphs anywhere where a paragraph already exists, but we haven't worked out a reliable way to do that yet.

I agree with this, I like the idea that if a paragraph exists, it's possible to add another one, and to give a little more flexibility to the content editing side of things. That said, given that the contentOnly behaviour is hidden behind an experiment, I think we could continue iterating on and trying out ideas here in subsequent PRs. And for the areas that aren't hidden behind an experiment, this appears to fix up some bugs and inconsistencies.

For now, I think this PR adds a good level of consistency and makes things feel solidly locked down, so this LGTM. But do feel free to seek another approving review if we're unsure of any of the particulars here!

if (
blockEditingMode === 'contentOnly' &&
! isContainerInsertableToInWriteMode( state, blockName, rootClientId )
( isParentSectionBlock || blockEditingMode === 'contentOnly' ) &&
Copy link
Contributor

Choose a reason for hiding this comment

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

We could maybe look at removing it when we get to updating the zoom out logic (i.e. as part of #71807).

Comment on lines 339 to 379
await test.step( 'Blocks cannot be inserted before/after', async () => {
// Test block with overrides.
await editor.selectBlocks( blockWithOverrides );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();

// Test block without overrides.
await editor.selectBlocks( blockWithoutOverrides );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();

// Test first button.
await editor.selectBlocks( firstButton );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();

// Test second button.
await editor.selectBlocks( secondButton );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this step redundant? It appears to use the same approach to check that insert before/after is not available as the duplication step, so thy could probably be combined? (I.e. in both cases, checking that Options is not available suffices.

Comment on lines 215 to 245
await test.step( 'Blocks cannot be inserted before/after', async () => {
// Test paragraph.
await editor.selectBlocks( paragraph );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();

// Test first list item.
await editor.selectBlocks( firstListItem );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();

// Test second list item.
await editor.selectBlocks( secondListItem );
await editor.showBlockToolbar();

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Options' } )
).toBeHidden();
} );
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to the other test, is this step redundant? (It appears to test the same thing as the previous step)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, true. AI wrote the tests, and I didn't look over the results enough! The code was originally checking for the specific menu items, but then Claude realized the menu doesn't exist at all, so that's how it ended up like it.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be fair, the duplicate test is correct 😄

state.settings.templateLock,
getBlockEditingMode( state, rootClientId ),
getSectionRootClientId( state ),
isSectionBlock( state, rootClientId ),
Copy link
Contributor

Choose a reason for hiding this comment

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

From looking at isSectionBlock it seems relatively simple in that it doesn't do too many lookups / calculations. But since it's being added to the list of dependencies just thought I'd double-check, do you think this has any potential performance concerns? My hunch is "no" 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's simple enough not to cause an issue. getParentSection is one I was concerned about though, it is used in the selector, but I haven't added it in the deps, so that might cause issues, though I didn't spot any.

"label": {
"type": "string"
"type": "string",
"role": "content"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to mention that there's a problem in trunk that this partially solves.

In the navigation editor (in the site editor), the navigation block there is set to a contentOnly block editing mode, and it's also a content block, which means it can now only have other content blocks inserted within it.

In trunk it means you can't insert a 'Home Link' block at all because it's not a content block. This was caught by a test, so I'm fixing it here.

While I've fixed Home Link, there might be other blocks that are affected (third party blocks too). It might be a back compat break (not to mention an issue in 6.9). We might need to consider again how that editor or the contentOnly insertion thing works. Maybe some kind of exception is needed for the navigation block, or maybe we can use a different technique to make sure the Navigation block can't be removed.

cc @getdave @jeryj @scruffian to make you aware of this. I'll also make an issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ramonjd
Copy link
Member

ramonjd commented Oct 23, 2025

Also retested. LGTM - great test coverage.

As @andrewserong says, it makes things more consistent 👍🏻

@talldan talldan force-pushed the fix/content-only-insertion-removal-and-moving branch from a6e5c38 to 63cec0b Compare October 23, 2025 05:19
@talldan talldan merged commit 1de4360 into trunk Oct 23, 2025
35 of 36 checks passed
@talldan talldan deleted the fix/content-only-insertion-removal-and-moving branch October 23, 2025 07:05
@github-project-automation github-project-automation bot moved this from 🔎 Needs Review to ✅ Done in WordPress 6.9 Editor Tasks Oct 23, 2025
@github-actions github-actions bot added this to the Gutenberg 22.0 milestone Oct 23, 2025
@github-actions github-actions bot removed the Backport to WP 6.9 Beta/RC Pull request that needs to be backported to the WordPress major release that's currently in beta label Oct 23, 2025
gutenbergplugin pushed a commit that referenced this pull request Oct 23, 2025
* Fix confusion between clientId and rootClientId * Fix contentOnly insertion logic for blocks at root of section * Fix movers appearing in contentOnly mode * Rename selector that mentions write mode * Fix typo * Add e2e tests for synced patterns to ensure blocks cannot be moved duplicate or deleted * Update move behavior to disable movers for templateLock contentOnly * Add contentOnly templateLock tests for block duplication, insertion and moving * Add buttons example to pattern overrides test too * Fix selector memoization * Make the selectors work in a more similar fashion * Fix test * Allow moving for template lock of `insert` * Make home link a content block * Condense identical test cases ---- Co-authored-by: talldan <talldanwp@git.wordpress.org> Co-authored-by: tellthemachines <isabel_brison@git.wordpress.org> Co-authored-by: ramonjd <ramonopoly@git.wordpress.org> Co-authored-by: andrewserong <andrewserong@git.wordpress.org> Co-authored-by: scruffian <scruffian@git.wordpress.org>
@github-actions github-actions bot added the Backported to WP Core Pull request that has been successfully merged into WP Core label Oct 23, 2025
@github-actions
Copy link

I just cherry-picked this PR to the wp/6.9 branch to get it included in the next release: 6163fc4

@scruffian
Copy link
Contributor

Looks good, thanks for this.

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

Labels

Backported to WP Core Pull request that has been successfully merged into WP Core [Feature] Patterns A collection of blocks that can be synced (previously reusable blocks) or unsynced [Type] Bug An existing feature does not function as intended

6 participants