humanmade / humanmade/query-filter
Naming the inherited-query search field `s` (fix for #50) breaks non-search templates using `inherit:true` as an in-place filter
- Dominant language
- JavaScript
- Stars
- 123
- Forks
- 33
- Avg merge
- 6h 7m
- Merged PRs (30d)
- 5
Description
## Summary
I filed #50, and offered two alternative fixes there. The maintainer went
with the first one in #60 (rename the inherited-query field to `s`) — which
is what's causing this. The second option I suggested (fix `updateURL()`'s
JS special-case to match whatever field name the PHP side actually computes,
instead of changing the PHP to match the JS's hardcoded `'s'`) would not have
had this side effect, since it never required the field to stop being named
`query-s`.
The regression: `core/query { "inherit": true }` isn't only used on a
dedicated Search Results template — it's also a normal way to let a
`core/search` block filter an ordinary archive/taxonomy template (e.g.
`archive-{post_type}.html`, `taxonomy-{taxonomy}.html`) in place, using the
main query rather than a separate custom one. Since #60, submitting that
field on *any* of these templates writes WordPress's own native `s` param
into the URL. `s` is read during `WP::parse_request()` — before
`pre_get_posts` even runs — so `is_search()` becomes genuinely `true`, and
WordPress discards the archive/taxonomy template for `search.html` entirely.
The field stops filtering the archive and starts replacing the page.
## Root cause
`render_block_search()` (`inc/namespace.php`):
```php
$query_var = $inherit
? 's'
: sprintf( 'query-%d-s', $instance->context['queryId'] ?? 0 );
```
This only distinguishes "inherited" vs "not inherited." It can't distinguish
"this inherited query is the dedicated Search template" (where #50 needs
native `s`) from "this inherited query is an archive/taxonomy template
borrowing the main query just to filter itself" (where native `s` actively
breaks template selection).
## Reproduction
1. Add `core/search` inside `core/query { "inherit": true }` on a
`taxonomy-{taxonomy}.html` (or `archive-{post_type}.html`) template — not
`search.html`.
2. Load the archive normally; confirm it renders that template.
3. Submit a term in the search field.
4. **Expected:** the archive stays on its own template, results narrowed to
the term. **Actual:** `is_search()` is now `true` and WordPress renders
`search.html` instead — different layout, different content part, the
term-scoping from the archive/taxonomy template is gone.
## Suggested fix
Revisit the second option from #50: keep the inherited-query field named
`query-s` unconditionally (as before #60), and instead fix `updateURL()`'s
clear-on-empty special case to match that actual name rather than hardcoding
`'s'`. That fixes the original #50 bug (clearing the field on a real search
page) without ever changing what the URL param is named — so it can't also
flip `is_search()` on templates that were never meant to become the search
results page.
## Environment
- `humanmade/query-filter` v0.4.2
- WordPress 6.9, PHP 8.4
Happy to open a PR for the `updateURL()` fix if that direction sounds right.
## Disclosure
This issue was AI generated based on the findings in a debugging session.
Contributor guide
Research direction
Start at render_block_search() in inc/namespace.php, then locate updateURL() in the JavaScript implementation and trace its clear-on-empty handling. Reproduce the inherited-query search on an archive or taxonomy template and verify that the archive remains selected while clearing a real search-page field still works.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, php, wordpress
- Domain
- backend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100