Skip to content

Conversation

@t-hamano
Copy link
Contributor

@t-hamano t-hamano commented Dec 23, 2025

Closes #51402

What?

This PR adds anchor support to almost all dynamic blocks.

Why?

Efforts to add anchor support to dynamic blocks were made in the past in #44771. However, that work also affected static blocks, potentially breaking them, so it was eventually reverted.

To add consistent anchor support regardless of whether the block is dynamic or static, the anchor is now always kept in comment delimiters (See #70993). This means we can now add anchor support to dynamic blocks.

How?

  • Add anchor support to almost all dynamic blocks.
  • Add server-side rendering of anchor support.
  • Add unit tests.

As a result, these are the blocks that do not support anchors. The reason I didn't enable it is either:

  • It's a static block, so it's outside the scope of this PR.
  • It's an experimental block.
  • Deprecated block.
  • The anchor doesn't work on this block.
Name Title
core/navigation-overlay-close Navigation Overlay Close
core/tabs Tabs
core/accordion-panel Accordion Panel
core/accordion-item Accordion Item
core/pattern Pattern Placeholder
core/template-part Template Part
core/missing Unsupported
core/freeform Classic
core/block Pattern
core/html Custom HTML
core/shortcode Shortcode
core/text-columns Text Columns (deprecated)
core/post-comment Comment (deprecated)
core/form-submission-notification Form Submission Notification
core/form-submit-button Form Submit Button
core/comment-author-avatar Comment Author Avatar (deprecated)

Testing Instructions

  • Insert any of the dynamic blocks.
  • Open the Advanced panel and apply an anchor string.
  • Save the post and open the post.
  • Confirm that the block has an id attribute.

@t-hamano t-hamano self-assigned this Dec 23, 2025
@github-actions github-actions bot added the [Package] Block library /packages/block-library label Dec 23, 2025
@t-hamano t-hamano force-pushed the dynamic-anchor-block-support branch from bd79ce2 to af17ec0 Compare December 23, 2025 10:35
@t-hamano t-hamano added [Feature] Block API API that allows to express the block paradigm. [Type] Enhancement A suggestion for improvement. labels Dec 23, 2025
@t-hamano t-hamano force-pushed the dynamic-anchor-block-support branch from af17ec0 to ade13f4 Compare December 23, 2025 11:02
@github-actions
Copy link

github-actions bot commented Dec 23, 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: t-hamano <[email protected]>
Co-authored-by: SirLouen <[email protected]>
Co-authored-by: aaronrobertshaw <[email protected]>
Co-authored-by: Mamaduka <[email protected]>
Co-authored-by: stefanfisk <[email protected]>

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

@Mamaduka
Copy link
Member

The anchor doesn't work on this block.

Is this due to the nature of the block (Classic, HTML, blocks without a wrapper) or some other limitation with the feature?

@github-actions
Copy link

github-actions bot commented Dec 23, 2025

Flaky tests detected in 17a3b1d.
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/20487968254
📝 Reported issues:

@Mamaduka Mamaduka requested a review from Soean December 23, 2025 12:37
Copy link
Member

@SirLouen SirLouen left a comment

Choose a reason for hiding this comment

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

@t-hamano I've tested it, and it's looking good. ✅

But there are two proposed changes to the unit tests:

  1. The file should end in -test.php so in this case anchor-test.php
  2. Can you add this test to the data provider?
'anchor with zero string is applied' => array(
	'support'  => true,
	'value'    => '0',
	'expected' => array( 'id' => '0' ),
),

And test it?

Copy link
Contributor

@aaronrobertshaw aaronrobertshaw 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 well for me 👍

Other than the suggested rename of the test file and the additional test cases, I think this is pretty close. While updating the test cases I think we could cover some more edge cases there.

Some possible test cases
public function data_anchor_block_support() {
    return array(
        'anchor id attribute is applied' => array(
            'support'  => true,
            'value'    => 'my-anchor',
            'expected' => array( 'id' => 'my-anchor' ),
        ),
        'anchor id attribute is not applied if block does not support it' => array(
            'support'  => false,
            'value'    => 'my-anchor',
            'expected' => array(),
        ),
        'empty anchor value returns empty array' => array(
            'support'  => true,
            'value'    => '',
            'expected' => array(),
        ),
        'null anchor value returns empty array' => array(
            'support'  => true,
            'value'    => null,
            'expected' => array(),
        ),
        'whitespace-only anchor value is applied' => array(
            'support'  => true,
            'value'    => '   ',
            'expected' => array( 'id' => '   ' ),
        ),
        'anchor with hyphen and numbers' => array(
            'support'  => true,
            'value'    => 'section-123',
            'expected' => array( 'id' => 'section-123' ),
        ),
        'anchor with underscore' => array(
            'support'  => true,
            'value'    => 'my_anchor_id',
            'expected' => array( 'id' => 'my_anchor_id' ),
        ),
        'anchor with colon (valid in HTML5)' => array(
            'support'  => true,
            'value'    => 'my:anchor',
            'expected' => array( 'id' => 'my:anchor' ),
        ),
        'anchor with period (valid in HTML5)' => array(
            'support'  => true,
            'value'    => 'my.anchor',
            'expected' => array( 'id' => 'my.anchor' ),
        ),
        'numeric anchor value' => array(
            'support'  => true,
            'value'    => '123',
            'expected' => array( 'id' => '123' ),
        ),
        'zero value is treated as empty' => array(
            'support'  => true,
            'value'    => 0,
            'expected' => array(),
        ),
        'false value is treated as empty' => array(
            'support'  => true,
            'value'    => false,
            'expected' => array(),
        ),
    );
}

I primarily tested with the Calendar, Latest Comments, Search, and Navigation blocks but did randomly try several more. Each worked as per the test instructions.

Screen.Recording.2025-12-23.at.5.33.23.pm.mp4

@t-hamano
Copy link
Contributor Author

Thanks everyone for the reviews!

Is this due to the nature of the block (Classic, HTML, blocks without a wrapper) or some other limitation with the feature?

These blocks don't seem to work because they don't have a block wrapper in the first place.

On the other hand, I thought we could add anchor support to the Template Part block, but it didn't work properly. Perhaps there's a problem with the server-side rendering code. I'll investigate this in a follow-up.

But there are two proposed changes to the unit tests:
While updating the test cases I think we could cover some more edge cases there.

Updated the test cases 👍

Comment on lines +123 to +127
'zero string anchor value is applied' => array(
'support' => true,
'value' => '0',
'expected' => array( 'id' => '0' ),
),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

While this test result is correct, it doesn't actually produce the expected results. That is, when you set an ID value of zero, it doesn't actually render.

This is likely an issue with get_block_wrapper_attributes() function, which causes falsy values ​​to be skipped.

https://github.com/WordPress/wordpress-develop/blob/814279bbce8c938e437d3c7a12976419ca8a0c8a/src/wp-includes/class-wp-block-supports.php#L187

This issue should also occur with className support and ariaLabel support.

I'll submit a follow-up core ticket regarding this.

Copy link
Member

Choose a reason for hiding this comment

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

Right, empty() will return true for '0' and 0.

Copy link
Member

@Mamaduka Mamaduka 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 test well for me ✅

@t-hamano t-hamano dismissed SirLouen’s stale review December 25, 2025 09:16

Request changes have already been addressed.

@t-hamano t-hamano merged commit 39e6777 into trunk Dec 25, 2025
41 checks passed
@t-hamano t-hamano deleted the dynamic-anchor-block-support branch December 25, 2025 09:18
@github-actions github-actions bot added this to the Gutenberg 22.4 milestone Dec 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Block API API that allows to express the block paradigm. [Package] Block library /packages/block-library [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Explore how to re-add anchor support to dynamic blocks

5 participants