Skip to content

fix(child-theme): Preserve navigation block refs when creating a child theme - #882

Open
KarunyaChavan wants to merge 2 commits into
WordPress:trunkfrom
KarunyaChavan:fix/child-theme-nav-refs
Open

KarunyaChavan wants to merge 2 commits into
WordPress:trunkfrom
KarunyaChavan:fix/child-theme-nav-refs

Conversation

@KarunyaChavan

@KarunyaChavan KarunyaChavan commented Oct 5, 2026 •

Copy link
Copy Markdown

This PR fixes a bug where navigation block ref attributes were unconditionally stripped from all template parts when using the "Create child theme" feature, causing distinct header and footer menus to collapse into the same fallback menu after the child theme was activated.

Fixes #866

Why?

  • The create_child_theme() method in [includes/create-theme/theme-create.php] called CBT_Theme_Templates::add_templates_to_local() without passing any $options, causing $options to be null all the way down the call chain.
  • In eliminate_environment_specific_content_from_block(), when $options is null, the guard condition ! $options is truthy and the ref attribute is always removed - regardless of user intent.
  • This default-to-strip behaviour is intentional only for ZIP exports (themes packaged for redistribution on an external site, where local database IDs are meaningless). It is not appropriate for creating a child theme on the same site, where the database is shared and navigation post IDs remain valid.
  • The consequence: both the header navigation block ({"ref": 224}) and the footer navigation block ({"ref": 229}) were exported with the ref stripped, causing WordPress core to trigger its fallback resolution and render both navigation areas using the same menu.
  • The sibling clone_current_theme() method in the same file has always passed explicit options ('removeNavRefs' => false) and was not affected. The child theme code path was simply never updated when removeNavRefs was introduced.

What Changed?

  • includes/create-theme/theme-create.php - create_child_theme():

    • Defined $template_options with removeNavRefs => false, localizeText => false, and localizeImages => false.
    • Passed $template_options as the 4th argument to CBT_Theme_Templates::add_templates_to_local().
    • Added two focused inline comments: one explaining why the options are set, one labelling the write operations - aligning with the comment style used in clone_current_theme().
    • No changes to any other method or file in the production code path.
  • tests/test-theme-templates.php - Test_Create_Block_Theme_Templates:

    • Added test_not_eliminate_nav_block_ref_nested_with_template_options to assert that a navigation block nested inside a group block retains its ref attribute when prepare_template_for_export() is called with removeNavRefs => false.
    • This directly covers the child theme template options shape, complementing the existing test_not_eliminate_nav_block_ref test (which only covers a top-level navigation block with a partial options array).
    • Added docblock comment for the new test case.

Steps for Testing

Setup:

  • Ensure Twenty Twenty-Four (or any block theme with navigation blocks) is the active theme.
  • Ensure the Create Block Theme plugin is active.

Reproduce the bug (on trunk before this PR):

  1. In the Site Editor, open Appearance > Editor > Patterns > Template Parts > Header.
  2. Select the Navigation block and assign it a named menu (e.g. Header Menu). Save.
  3. Open the Footer template part. Add or select a Navigation block and assign a different menu (e.g. Footer Menu). Save.
  4. Open Create Block Theme > Create child theme, provide a name, and create it.
  5. Inspect parts/header.html and parts/footer.html in the new child theme folder:
    • Expected: <!-- wp:navigation {"ref":X,...} /--> - ref preserved.
    • Before this fix (Actual): <!-- wp:navigation /--> - ref stripped.
  6. Visit the frontend - both Header and Footer render the same menu.

Verify the fix (on this branch):

  1. Delete the previously created child theme folder.
  2. Repeat steps 1–4 above.
  3. Inspect the exported template parts:
    • header.html should contain "ref":<header-menu-id>.
    • footer.html should contain "ref":<footer-menu-id>.
  4. Visit the frontend - Header and Footer display their distinct, separately assigned menus.

Use of AI

  • AI Assistance Used: Yes
  • Tool: Antigravity
  • Model: Gemini 3.1 Pro
  • Used for: Adding tests to cover the updated patch. The results were reviewed and verified by me.

- Pass template options with removeNavRefs set to false to add_templates_to_local() in create_child_theme()
- Prevent unconditional stripping of ref attributes from core/navigation blocks in child theme templates
- Avoid navigation collisions where distinct menus fall back to the same menu resolution
- Align child theme template export options with the pattern used in clone_current_theme()
- Add test_not_eliminate_nav_block_ref_nested_with_template_options test case
- Assert that nested navigation blocks retain their ref attribute when removeNavRefs is false
@KarunyaChavan
KarunyaChavan marked this pull request as ready for review October 5, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Navigation block ref is always stripped when creating a child theme, causing menu references to be lost/mismatched

1 participant