-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tax Query: Allow querying for all posts with any term of a given taxonomy #7271
base: trunk
Are you sure you want to change the base?
Tax Query: Allow querying for all posts with any term of a given taxonomy #7271
Conversation
Test using WordPress PlaygroundThe 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
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
Noting here that if we don't want to implement this kind of behavior universally for all taxonomies, we could add an argument to |
7baa25c
to
d3b5c55
Compare
ca67943
to
38d1d42
Compare
add_rewrite_tag( "%$this->name%", $tag, $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term=" ); | ||
$query = $this->query_var ? "{$this->query_var}=" : "taxonomy=$this->name&term="; | ||
|
||
add_rewrite_tag( "%taxonomy-$this->name%", "$this->name()", $query ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trailing ()
here is a RegEx capturing group. WordPress really wants to retrieve a match from this RegEx that it'll use as the value in the query string; it'll automatically build a query string like this: ?key=$matches[0]
, using the $matches
var resulting from applying the RegEx.
Since we don't want to set any value, we work around this by providing a capturing group that will return the empty string, thus resulting in ?key=
.
The recent proposal from @youknowriad about architectural changes to how templates get linked with themes might resolve this issue because we would finally be able to have 1 template file applicable in multiple scenarios: |
This reverts commit 6150936.
66a05a8
to
91ddfda
Compare
AFAIU that proposal would allow the user to assign custom templates to any template "entity" in the template hierarchy (i.e. to any red, green, or blue box in this diagram). This means that it'd be still somewhat coupled to the template hierarchy, as opposed to allowing assigning a custom template to any given route. As a consequence, I think we'd still need to extend the template hierarchy to contain a template "entity" that's shared between existing taxonomy archive template entities (i.e. |
BTW as discussed on our call the other day, extending the template hierarchy isn't particularly complex, but very cumbersome, and there are a few different ways to do that. I started implementing that as part of this PR but have now removed the relevant commits. I'd rather tackle that in a separate PR so that this one can solely focus on enabling the root taxonomy routes, without involving the template hierarchy yet. I'll update the PR description accordingly. |
Diff best viewed with whitespace changes hidden.
What
Introduce a new
register_taxonomy()
flag (tentatively calledroot_taxonomy_archive
) which, for a given taxonomy — e.g.projects
— will enable the "root" route (/projects
) (so it no longer is interpreted as a page that doesn’t exists and thus 404s).Note that this does not extend the template hierarchy to include a dedicated template for root taxonomy archives; that is a different problem that I’d like to tackle separately. For now, root taxonomy routes fall back to the generic archive template.
How
To solve this problem, we need some understanding of WordPress' routing. Internally, there are two important concepts:
%year%
or%postname%
, and defined viaadd_rewrite_tag()
, where the matching regular expression is provided as an argument; e.g. for%year%
– a four-digit number – the RegEx is([0-9]{4})
.key=value
pairs, from which it assembles a query string -- which is the canonical representation for any route! E.g./2024/12/hello-world
is matched by/%year%/%month%/%postname%
, which is then translated into/?year=2024&month=12&name=hello-world
.For a taxonomy called
projects
, the permastruct is/projects/%project%
. Then, a route such as/projects/film
is mapped to the query string?projects=film
, as can be easily verified using the Query Monitor plugin.The crux here is WordPress' rigid mapping of any rewrite tag to a key/value pair, used in a query string (like
?key=value
). Thus, the first part of the solution found in this PR is to allow a "dangling" query string, i.e.?projects=
(with no value assigned). Note that this is not in violation of the URI RFC!The second part is to define a permastruct that matches a route like
/projects
and translates it to that "dangling"?projects=
query string. The tricky part here is that WordPress really, really wants us to use a rewrite tag that it will match against the route, and use the value it finds as the value in the query string. We work around this by adding a RegEx capturing group that will match the empty string:()
.Testing instructions
functions.php
). Create a number of new posts, and use the "Project Types" panel in the block inspector to create a number of "Project Type" terms and assign them to each given post. Use terms such as "Film" or "TV".Code
Go to Settings > Permalinks, and click the "Save changes" button at the bottom. (This is required for WordPress to update its internal routing to include routes for the newly added taxonomy.)
Manually navigate to
/projects/film
and verify that it still works, displaying an archive of posts that have the "Film" term assigned.Manually navigate to
/projects
and verify that it also works: It should show an archive of all posts that have at least one term from theprojects
taxonomy assigned. (It will currently use the generic archive template. Adding a template for the root taxonomy route will be handled in a follow-up.)(You can compare this behavior to
trunk
, where/projects
will 404.)Finally, also try the query strings
?projects=film
and?projects=
. They should also display the correct archives.Follow-up work
In #7989, I've started exploring extending the permalink structure to include a dedicated template for the root taxonomy route.
References
Some relevant documentation here.
Screencast
Trac ticket: https://core.trac.wordpress.org/ticket/61957
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.