My categories are basically authors, and I would like to create a function to list them according to their surname. For example I’d like to have something like:

E:

  • Heinz Erhardt
  • Albert Einstein
  • Eminem

The problem is, I also have authors with only one name (like “Eminem”) which I would also like to be sorted according to the letter E.
The only way I know of to do this in wordpress is with the get_terms function and the name__like.

function getAuthors(){
$args = array(
    'name__like' => 'E',
);
return get_terms('category', $args );
}

this creates the sql query which only lists categories with an “E” in it:

AND t.name LIKE %E%;

I however need something like:

AND t.name NOT LIKE '% %' AND t.name LIKE E% OR t.name LIKE '% E';

I tried to change the code in the get_terms function in the core file where the query is set up (taxonomies.php, line 1809). However I wasn’t successfull and I wouldn’t like to change something in the core files.

How can I customize the query passed by the name__like? Are there other better ways I can achieve my goal?

— EDIT —

I used TheDeadMedic’s solution and was able to list categories according to a specific letter by using for example get_terms( 'my_taxonomy', 'surname=E' ); However this surname argument doesn’t work if I want to use the get_terms function multiple times on one page (for example in a loop – if I’d like to create A-Z headings and display the according sorted categories below the headings).

Here’s the function I’m trying to execute. The problem is that it just keeps listing the categorys for surname=A under every heading.

function getAuthors()
{
$letters = range('A', 'Z'); // create Alphabet array
foreach ($letters as $letter) {
    echo '<h4>' . $letter . '</h4>';
    $args = array(
        'surname' => $letter
    );
    $cats = get_terms('category', $args);

    foreach ($cats as $cat) {
        echo "<ul>";
        echo "<li>" . $cat->name . "</li>";
        echo "</ul>";
    }
  }
}

The name__like argument seems to work in the loop though.

2 Answers
2

Use the terms_clauses filter, which passes all the various components of the query (fields, join, where, orderby, order & limits), and implement your own “search” argument:

function wpse_178511_get_terms_fields( $clauses, $taxonomies, $args ) {
    if ( ! empty( $args['surname'] ) ) {
        global $wpdb;

        $surname_like = $wpdb->esc_like( $args['surname'] );

        if ( ! isset( $clauses['where'] ) )
            $clauses['where'] = '1=1';

        $clauses['where'] .= $wpdb->prepare( " AND t.name LIKE %s OR t.name LIKE %s", "$surname_like%", "% $surname_like%" );
    }

    return $clauses;
}

add_filter( 'terms_clauses', 'wpse_178511_get_terms_fields', 10, 3 );

Put in use:

 get_terms( 'my_taxonomy', 'surname=E' );

Leave a Reply

Your email address will not be published. Required fields are marked *