WordPress / WordPress/create-block-theme
Navigation block ref is always stripped when creating a child theme, causing menu references to be lost/mismatched
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 417
- Forks
- 66
- PR merge metrics
- No merged PRs in 30d
Description
Description
When creating a child theme via the "Create child theme" feature, the ref attribute is unconditionally removed from every core/navigation block in every exported template part — regardless of any user setting.
This causes navigation blocks that were pointing at distinct menus (e.g. a header menu vs. a footer menu) to lose that association. After WordPress falls back to resolving a navigation without an explicit ref, the wrong menu can end up being displayed (for example, the header ends up showing what was previously the footer's menu).
Steps to reproduce
Reproduced with the default Twenty Twenty-Four theme (no other plugins involved), so this is not theme-specific:
- Create two distinct
wp_navigationposts (e.g. "Header Menu" and "Footer Menu"). - Set the header template part to reference one (
<!-- wp:navigation {"ref":4} /-->) and the footer template part to reference the other (<!-- wp:navigation {"ref":5} /-->). - Use Create Block Theme's "Create child theme" action to generate a child theme.
- Inspect the exported child theme's
parts/header.htmlandparts/footer.html.
Expected: each Navigation block keeps referencing its original menu (ref:4 / ref:5).
Actual: both ref attributes are gone:
<!-- header.html -->
<!-- wp:navigation /-->
<!-- footer.html -->
<!-- wp:navigation /-->
No error is raised — the reference is silently lost. In a real site, this typically manifests as the header ending up showing what was previously the footer's menu (or vice versa), once WordPress core falls back to resolving a navigation without an explicit ref.
Likely cause
In includes/create-theme/theme-templates.php:
private static function eliminate_environment_specific_content_from_block( $block, $options = null ) {
...
// (optionally) remove ref attribute from nav blocks
if ( 'core/navigation' === $block['blockName'] && isset( $block['attrs']['ref'] ) ) {
if ( ! $options || ( array_key_exists( 'removeNavRefs', $options ) && $options['removeNavRefs'] ) ) {
unset( $block['attrs']['ref'] );
}
}
When $options is null, the ref is removed unconditionally.
In includes/create-theme/theme-create.php, create_child_theme() calls:
CBT_Theme_Templates::add_templates_to_local( 'user', $new_theme_path, $theme['slug'] );
...without passing an $options argument, so $options defaults to null all the way down to eliminate_environment_specific_content_from_block(), and the ref is always stripped.
This differs from clone_current_theme() in the same file, which explicitly passes:
$template_options = array(
'localizeText' => false,
'removeNavRefs' => false,
'localizeImages' => false,
);
...so navigation refs are preserved when cloning the current theme. It looks like create_child_theme() was simply never updated to pass the same (or an equivalent) $options array.
This seems related to, but distinct from, #574 (fixed via #572), which addressed the "Save Changes" panel flow reprocessing all templates instead of only changed ones. The "Create child theme" flow appears to be a separate code path that wasn't covered by that fix.
Environment
- Create Block Theme: 2.10.1 (originally observed), reproduced against current
trunk - WordPress: 7.1
- Theme: reproduced with the default Twenty Twenty-Four theme via WP Playground — confirms this is not specific to any particular theme; originally reported against a third-party theme ("X-T9")
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in includes/create-theme/theme-create.php at create_child_theme(), then compare its template options with clone_current_theme(). Trace the options into includes/create-theme/theme-templates.php and reproduce with distinct navigation refs in parts/header.html and parts/footer.html. Done means the generated child theme preserves each original navigation ref instead of stripping both.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, wordpress
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 85/100