Navigation: Restore block_core_navigation_submenu_render_submenu_icon() as deprecated shim#78484
Conversation
…() as deprecated shim In WordPress#74853 the function was removed from packages/block-library/src/navigation-submenu/index.php without a _deprecated_function() notice. Once that change synced into Core (wordpress-develop WordPress#10865, scheduled for WP 7.0), themes and plugins that called the function — for example from a render_block_core/navigation-submenu filter — started fatal-erroring. This restores it as a thin wrapper that triggers _deprecated_function() and returns block_core_shared_navigation_render_submenu_icon(), the new shared helper that replaced it. Adding it to the shared file means it's available wherever the original was previously rendered. A phpunit test asserts the deprecation notice fires and the return value matches the new helper. Trac ticket: https://core.trac.wordpress.org/ticket/65287
|
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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @ecairol! In case you missed it, we'd love to have you join us in our Slack community. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
PHPCS in packages/block-library/src/navigation-link/shared/ enforces a function-name prefix of block_core_shared*, which forbids the deprecation shim's name. Move the shim into navigation-submenu/index.php (where the function originally lived and block_core_navigation_submenu_* is allowed), guarded by function_exists so a future Core sync that brings the shim back into Core doesn't double-declare. Drop the require_once in the test — its path resolution differed from the plugin's own init load and was triggering "Cannot redeclare" fatals against the already-loaded block_core_shared_navigation_render_submenu_icon(). Normal plugin boot loads navigation-submenu/index.php during block registration, so the shim is available to the test without an explicit require.
The build prefixes packages/block-library functions with gutenberg_ before the plugin loads them, so in the plugin test env the shim exists as gutenberg_block_core_navigation_submenu_render_submenu_icon, not the unprefixed Core name. Match the existing block-navigation-link-variations test convention of asserting on the prefixed name with setExpectedDeprecated().
| * | ||
| * @return string SVG markup for the submenu icon. | ||
| */ | ||
| function block_core_navigation_submenu_render_submenu_icon() { |
There was a problem hiding this comment.
Just checking something... the PR description says it should live in packages/block-library/src/navigation-link/shared/render-submenu-icon.php.
To be clear, packages/block-library/src/navigation-submenu/index.php is fine since it was first deleted here:
There was a problem hiding this comment.
Good catch, thank you — you're right that the description was stale. I started with the shim in render-submenu-icon.php (commit 1), then moved it into navigation-submenu/index.php (commit 2) because PHPCS in the navigation-link/shared/ directory only accepts function names matching the block_core_shared* prefix. I just updated the PR description to match the code, and linked to the same L87 deletion you pointed at as the justification for the placement. Appreciate the review!
|
LGTM thanks for the quick patch @ecairol 🙇🏻 @scruffian @getdave do you think this is worth a point release? if so, we might need to coordinate with @ellatrix or someone in the release squad. |
| require_once __DIR__ . '/navigation-link/shared/render-submenu-icon.php'; | ||
| require_once __DIR__ . '/navigation-link/shared/build-css-font-sizes.php'; | ||
|
|
||
| if ( ! function_exists( 'block_core_navigation_submenu_render_submenu_icon' ) ) { |
There was a problem hiding this comment.
Wrapped in a
function_existsguard so a future Core sync that brings the shim back to Core itself doesn't double-declare.
I don't think a double declaration can occur, so we can remove this function existence check.
There was a problem hiding this comment.
Agreed. The only way that comes to mind would be if a theme/plugin declares it after seeing it doesn't exist in 7.0, but it's as rare an edge case as using the function in a theme/plugin in the first place.
| /** | ||
| * @group blocks | ||
| */ | ||
| class Block_Core_Navigation_Submenu_Render_Submenu_Icon_Test extends WP_UnitTestCase { |
There was a problem hiding this comment.
The existence test for a deprecated function felt a bit like overkill to me. Is it really necessary? I'm generally fine with regression tests, but I don't see a good need for that, unless it's actually used somewhere.
| require_once __DIR__ . '/navigation-link/shared/render-submenu-icon.php'; | ||
| require_once __DIR__ . '/navigation-link/shared/build-css-font-sizes.php'; | ||
|
|
||
| if ( ! function_exists( 'block_core_navigation_submenu_render_submenu_icon' ) ) { |
There was a problem hiding this comment.
Agreed. The only way that comes to mind would be if a theme/plugin declares it after seeing it doesn't exist in 7.0, but it's as rare an edge case as using the function in a theme/plugin in the first place.
| * Renders the submenu icon SVG for the Navigation Submenu block. | ||
| * | ||
| * @since 5.9.0 | ||
| * @deprecated 7.0.0 Use block_core_shared_navigation_render_submenu_icon() instead. |
There was a problem hiding this comment.
Just to confirm, it's intended to land in a patch version?
| * In Gutenberg plugin builds, the function name is prefixed with `gutenberg_` | ||
| * by the build system to avoid colliding with the WordPress Core version. These | ||
| * tests therefore exercise the prefixed name; the unprefixed counterpart is the | ||
| * one Core ships once the change syncs back. |
There was a problem hiding this comment.
Is this really true for this function? I see no prefixing happening with that function at all.
There was a problem hiding this comment.
Apologies. This was AI adding unnecessary comments. Apparently, there's an automatic prefixing at build that prepends gutenberg_:
The build genuinely rewrites function NAME( → function gutenberg_NAME( for everything under packages/block-library/src/**/*.php
However, the comment was pure noise, and it's been removed now (84e2c4a)
|
Added the label to backport this to the next minor WP release, as that seems like the likeliest thing that will happen. |
|
Looks like the PHP test caused a CI failure on trunk, I expect it might need to be gated by WordPress version or something. I can follow up on it. |
|
Ah, I don't think that matrix runs on PRs. I guess we could guard the test so it only runs when the shared core helper exists. I dunno. if ( ! function_exists( 'block_core_shared_navigation_render_submenu_icon' ) ) {
$this->markTestSkipped( 'block_core_shared_navigation_render_submenu_icon() is not available in this WordPress version.' );
} |
|
It should be fixed via d8688b2 |

What
Restores
block_core_navigation_submenu_render_submenu_icon()as a deprecation shim and removes the backwards-incompatibility introduced by #74853.Why
In #74853 the function was removed from
packages/block-library/src/navigation-submenu/index.phpas part of consolidating submenu icon rendering into the new shared helperblock_core_shared_navigation_render_submenu_icon(). The removal landed without a_deprecated_function()notice or a backwards-compatible alias.Once that change synced into Core (wordpress-develop #10865, scheduled for WordPress 7.0), any theme or plugin that called the function — for example from a
render_block_core/navigation-submenufilter to customise the dropdown chevron — started triggering a fatal PHP error.Trac ticket: https://core.trac.wordpress.org/ticket/65287
How
packages/block-library/src/navigation-submenu/index.php— the same file the original was first deleted from.Wrapped in afunction_existsguard so a future Core sync that brings the shim back to Core itself doesn't double-declare._deprecated_function()so callers see actionable guidance to migrate to the new shared helper, and returns the new helper's output to preserve the rendered markup.gutenberg_-prefixed name (matching the build's plugin output and the existingblock-navigation-link-variations-test.phpconvention).Notes for reviewers
The build's
gutenberg_prefix transform (packages/wp-build/lib/build.mjs:413-422) applies to plugin builds but is skipped for Core (IS_WORDPRESS_COREbranch at L392-397). That means:block_core_navigation_submenu_render_submenu_icon()unprefixed — fixes the fatal on standalone Core installs.gutenberg_block_core_navigation_submenu_render_submenu_icon(). On WP 7.0+ + plugin, theme calls to the unprefixed name resolve to Core's shim (once synced), so the bug is fixed there too.Testing Instructions
block_core_navigation_submenu_render_submenu_icon()(e.g. inside arender_block_core/navigation-submenufilter).block_core_shared_navigation_render_submenu_icon().Also runnable:
phpunit --filter Block_Core_Navigation_Submenu_Render_Submenu_Icon_Test.Screenshots or screencast
N/A — backend-only change with no UI impact.
Types of changes
Bug fix (backwards-compatible).
Checklist