feat(customizer): disable the header and the footer for the whole site - #4628
Open
Alexia-Soare wants to merge 8 commits into
Open
Alexia-Soare wants to merge 8 commits into
Alexia-Soare wants to merge 8 commits into
Conversation
Add a Disable Header Globally toggle to the Header panel and a Disable Footer Globally toggle to the Footer panel. Both feed the existing neve_filter_toggle_content_parts filter, at a priority that runs after the post meta, so the site wide setting wins. Move the filter check outside the header element in both templates. The element used to be printed even when the header was off, which left an empty wrapper that held only the skip link. The skip link now sits outside the element, so it survives a disabled header. The builder panels hide every section they do not name, so both sections are added to the whitelist in the customizer styles. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The states were printed on neve_after_header_hook, which does not run when the header is off. One of them drives the WooCommerce shop sidebar, which stays on the page without a header. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add unit tests for the toggle, its precedence over the post meta, the markup of both templates and the customizer registration. Add end to end tests, one of which opens the builder panels, because a section can register and still be hidden by the panel styles. Complete the WooCommerce stub with the conditional tags, so tests that render body_class() after the cart tests do not fatal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Collaborator
Collaborator
🌍 i18n String Review Report📊 Summary
➕ Added Strings (4) - Click to expand
|
There was a problem hiding this comment.
Note
Copilot was unable to run its full agentic suite in this review.
Pull request overview
Adds global header/footer visibility toggles, ensuring disabled parts don’t leave empty wrappers behind and that related compatibility output (AMP/FSE) still renders correctly.
Changes:
- Introduces Customizer controls for globally disabling the header and/or footer.
- Implements a global visibility filter and updates header/FSE rendering to drop wrappers while preserving the skip link.
- Adds unit + e2e coverage and extends test stubs for WooCommerce/AMP conditionals.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test-neve-global-header-footer.php | Adds PHPUnit coverage for global toggles, markup expectations, Customizer registration, and AMP/FSE interactions. |
| tests/stubs/woocommerce-cart.php | Extends WooCommerce stub with additional conditional tag functions used by the theme. |
| tests/stubs/amp.php | Adds minimal AMP endpoint stub for AMP-mode rendering in tests. |
| inc/views/tweaks.php | Adds a late-running filter enforcing global header/footer visibility settings. |
| inc/customizer/options/header_footer_visibility.php | Registers new Customizer sections/controls for global header/footer visibility. |
| inc/customizer/loader.php | Loads the new Customizer options module. |
| inc/compatibility/fse.php | Adjusts FSE header output to avoid empty wrappers and keep skip link outside the header. |
| inc/compatibility/amp.php | Moves AMP state rendering to a wrapper-level hook so it persists without the header. |
| header.php | Adjusts classic theme header output to avoid rendering header wrapper when disabled; keeps skip link. |
| e2e-tests/specs/customizer/header-footer-visibility/header-footer-visibility.spec.ts | Adds Playwright coverage for Customizer controls visibility and front-end behavior. |
| assets/apps/customizer-controls/src/scss/_general.scss | Whitelists new Customizer sections so they’re visible in the builder panels. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The test case restores the hooks and rolls back the database, but it does not touch $wp_customize. Keep the previous value and put it back, the way the metabox test does with the REST server. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hold the panel, the section title and the control label in one array per part, in place of two ternaries. Assert on the toggle structure in the e2e spec, not on the English label. Check that the stylesheet exists before the test reads it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Drop the hook docblock copied into header.php. footer.php documents this filter and the block theme template carries none. Keep only the part of the filter docblock a reader cannot infer. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Collaborator
|
🤖 Review agent — queued ⏳ on Run |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Users who build their header and footer with a page builder had no way to turn off the theme header and footer for the whole site. The Customizer now has a toggle for each, and a disabled header no longer leaves an empty wrapper on the page.
What changed
Header panel — a new Header Visibility section holds a Disable Header Globally toggle. Footer panel — a new Footer Visibility section holds a Disable Footer Globally toggle. Both are off by default.
Header markup — the header element is no longer printed when the header is off. Before, the element stayed on the page and held only the skip link. The same change is applied to the block theme template in
inc/compatibility/fse.php.Skip link — printed outside the header element, so it stays available when the header is off.
Post meta — a page can still turn its own header or footer off. A page can no longer turn one back on against the global toggle.
AMP — the
amp-stateelements move fromneve_after_header_hooktoneve_after_header_wrapper_hook. One of them drives the WooCommerce shop sidebar, which stays on the page when the header is off.Customizer styles — both new sections are added to the whitelist in
_general.scss. The builder panels hide every section they do not name.Note
The toggle removes the whole header region, and page builders render into that region. Elementor Pro, Header Footer Elementor and Beaver Themer all hook
neve_do_headerandneve_do_footer, so their headers and footers go away too. This is intended: a user who wants a page builder header leaves the toggle off. Elementor Canvas templates never callget_header(), so they do not change.Note
The metabox writes
offboth for an untouched page and for a page that was turned on and off again. The value cannot tell the two apart, so the global toggle wins over it. Issue #4551 lists the per page override as optional.What decides if the header renders
flowchart LR A["Page loads"] --> B{"Post meta<br/>set to on?"} B -- yes --> C["No header"] B -- no --> D{"Changed:<br/>Disable Header<br/>Globally?"}:::changed D -- yes --> E["New:<br/>No header element,<br/>skip link stays"]:::added D -- no --> F["Header renders"] classDef added fill:#1a7f37,color:#fff,stroke:#116329,stroke-width:3px classDef changed fill:#9a6700,color:#fff,stroke:#5c3d00,stroke-width:3px,stroke-dasharray:6 3QA
Go to
WP Admin → Appearance → Customize → Header. Find the Header Visibility section above Header Presets. Turn on Disable Header Globally and publish.Expect: the preview loses the header. No empty gap stays at the top.
Open the site front end in a new tab. Open the page source with
Ctrl+UorCmd+Option+U. Search for<header.Expect: no match. Search for
neve-skip-link. One match stays.Open a category archive and a search results page, for example
/?s=test.Expect: no header on either page. The page metabox never covered these views.
Open a single page in the editor. In the sidebar, open Neve Options. Turn Disable Header on, update, then turn it off and update again.
Expect: with the global toggle on, the page has no header in both states.
Turn off Disable Header Globally. On the same page, set Disable Header to on and update.
Expect: this page has no header. Every other page keeps its header.
If WooCommerce is active, set the global toggle on and open the shop archive.
Expect: no header. The shop archive reads meta from the Shop page, and the global toggle still wins.
Go to
WP Admin → Appearance → Customize → Footer. Turn on Disable Footer Globally and publish. Open the front end and search the source forid="site-footer".Expect: no match. The page still ends with
</body>.#4551
🤖 Generated with Claude Code