Opened 8 years ago
Last modified 5 years ago
#40335 new defect (bug)
using 'pre_get_terms' is confusing when it comes to ordering by meta
Reported by: | wujek_bogdan | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 4.7.3 |
Component: | Query | Keywords: | |
Focuses: | Cc: |
Description
There's a pre_get_terms
hook. One might think that it works in the same way how pre_get_posts
works, but it doesn't.
I wanted to order terms by a meta field, so I did something like this:
<?php add_action('pre_get_terms', function (\WP_Term_Query $query) { if ( SOME_CONDITION_HERE ) { return; } $queryVars = $query->query_vars; $args = [ 'meta_key' => 'my_meta_key', 'orderby' => 'meta_value', 'order' => 'ASC', ]; $query->query_vars = array_merge($queryVars, $args); });
And for pre_get_posts
this technique would work. But with pre_get_terms
it's different. Digging into WP_Term_Query
class code I found that this code would cause parse_orderby()
method to set the $maybe_orderby_meta
variable to true
. But it doesn't mean that terms will be sorted by a meta field. It only means that terms maybe will be sorted by meta.
There's an another filter required. At the end of the parse_orderby()
method there's an another filter applied: get_terms_orderby
.
So in order to sort terms by meta field there's one more thing required. Something like:
<?php add_filter('get_terms_orderby', function ($orderby, $args) { if ( SOME_CONDITION_HERE ) { return $orderby; } return 'meta_value'; }, 10, 2);
This is unintuitive and confusing, and what's the most important: it's not documented. The documentation should be very clear about it. Because of the filter name, that's very similar to the pre_get_posts
filter name, users might expect it to work in the same way. It might be even considered as a bug. So I'll mark it as a bug, because from the user's perspective this is how it looks like.
Change History (6)
#3
in reply to:
↑ 2
@
7 years ago
Replying to johnh10:
I'm running into the same issue, and am unable to user
pre_get_terms
to order the terms bymeta_value
. It does not work likepre_get_posts
at all.
Read the whole comment I wrote (or at least the last sentence ;)), at the bottom I've posted a solution.
#4
@
7 years ago
I've found no sane way to change the WP_Terms_List_Table
default or custom ordering. This could be avoided if the pre_get_terms
hook made by reference, much like pre_get_posts
:
so: do_action( 'pre_get_terms', $this );
to: do_action_ref_array( 'pre_get_terms', array( &$this ) );
then we can override meta_query
with new WP_Meta_Query
for custom ordering.
I'm running into the same issue, and am unable to user
pre_get_terms
to order the terms bymeta_value
. It does not work likepre_get_posts
at all.