WordPress.org

Make WordPress Core

Opened 15 months ago

Last modified 5 months 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 (4)

#1 @wujek_bogdan
15 months ago

  • Type changed from enhancement to defect (bug)

#2 follow-up: @johnh10
7 months ago

I'm running into the same issue, and am unable to user pre_get_terms to order the terms by meta_value. It does not work like pre_get_posts at all.

#3 in reply to: ↑ 2 @wujek_bogdan
6 months ago

Replying to johnh10:

I'm running into the same issue, and am unable to user pre_get_terms to order the terms by meta_value. It does not work like pre_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 @geminorum
5 months 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.

Note: See TracTickets for help on using tickets.