Skip to content

#37653 - Report the front page when the query was never parsed - #13538

Open
skikken wants to merge 2 commits into
WordPress:trunkfrom
skikken:fix/37653-is-front-page-empty-query
Open

skikken wants to merge 2 commits into
WordPress:trunkfrom
skikken:fix/37653-is-front-page-empty-query

Conversation

@skikken

@skikken skikken commented Sep 15, 2026

Copy link
Copy Markdown

A section or control whose active_callback is is_front_page never shows in the Customizer, because is_front_page() is false at the point the callback is evaluated.

The Customizer renders in wp-admin, and nothing there parses a front-end main query. $wp->main() only runs on the front end, from wp-blog-header.php, so $wp_query is still the bare new WP_Query() created in wp-settings.php. Because WP_Query::__construct() skips query() when the query string is empty, parse_query() never runs and none of the is_* flags are populated. They stay at their declared defaults of false, so every branch of is_front_page() falls through to false.

The same situation is already handled for a parsed query with an empty query string. parse_query() promotes is_page and demotes is_home when show_on_front is page, on the grounds that an empty query with a static front page is the front page. That logic is unreachable here only because it lives in the function that does not run for an unparsed query.

This tracks whether parse_query() has run and consults that in is_front_page(), so an unparsed query reporting a static front page is treated as the front page. It does not require a page to be selected, which is what 37653.2.diff gated on, and therefore also covers the intermediate state the Customizer can reach with no page chosen. That state is why the reporter said that patch did not work for him.

Scope notes:

  • WP_Query::__construct() is unchanged. Making it always call query() was the reporter's own suggestion in query.patch, which he described as a hack; it would change behaviour for every bare new WP_Query() in core, about 20 call sites in src/ alone, and an unparsed query is a state core relies on.
  • is_page() is unchanged. An unparsed query has no queried object, so there is nothing to match a page ID against, and a test pins that.
  • is_front_page() returns the same value as before for every parsed query. The tests assert the negative cases as well as the positive ones, including that a parsed query for a different page is still not the front page.

Trac ticket: https://core.trac.wordpress.org/ticket/37653

Use of AI Tools

AI assistance: Yes
Tool(s): Claude
Model(s): Sonnet
Used for: test cases, code review


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

is_front_page() is false for the Customizer's main query, so a section or
control using it as an active_callback never shows. The Customizer renders
in wp-admin, where nothing parses a front-end main query: $wp->main() only
runs on the front end from wp-blog-header.php, so $wp_query is still the
bare new WP_Query() from wp-settings.php. Since WP_Query::__construct()
skips query() for an empty query string, parse_query() never runs and none
of the is_* flags are populated. Every branch of is_front_page() therefore
falls through to false, for both 'posts' and 'page' on 'show_on_front'.

The same situation is already resolved for a parsed query with an empty
query string: parse_query() promotes is_page and demotes is_home when
'show_on_front' is 'page'. That logic is simply unreachable here, because
it lives in the function that does not run.

Track whether parse_query() has run and use that in is_front_page(), so an
unparsed query reporting a static front page is treated as the front page.
This does not depend on a page being selected, which is what the previous
patch on the ticket gated on, so it also covers the state the Customizer
can reach with no page chosen.

is_front_page() returns the same value as before for every parsed query,
and is_page() is unchanged, since an unparsed query has no queried object
to match against.

Props Guss77, westonruter.
Fixes #37653.
Add coverage for the state the Customizer evaluates active_callback in: a
WP_Query created with no arguments, whose is_* flags are all at their
defaults. Assert the static front page is reported as the front page, that
the posts-on-front configuration is not, and that the "no page selected"
state the Customizer can reach is handled too.

The tests for parsed queries guard the other direction, including that a
different page is still not the front page, that a parsed root request
keeps its existing is_front_page() and is_home() values, and that a parsed
query with an empty query string still resolves the static front page.

Refs #37653.
@github-actions

Copy link
Copy Markdown

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.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @skikken.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

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

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

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.

1 participant