0

I'm using get_tags (outside the loop) with the argument name__like to return tags containing one, two or three exact and specific words.

I already tried (not working):

$args = get_tags( 'orderby' => 'name','order' => 'ASC', array('name__like' => 'group', 'name__like' => 'worker', 'name__like' => 'student' ) );

and I also tried to use get_terms (not working):

$args = get_terms( 'post_tag', array('name__like' => 'group', 'name__like' => 'worker', 'name__like' => 'student') );

It only seems to work when I try to get tags containing only one word, like this:

$args = array('orderby' => 'name','order' => 'ASC','name__like' => 'worker',);

I'm finding a bit lost... Is not possible to use an array here?

This is the rest of my code, so far:

$tags = get_tags($args ); 
    if ( !empty( $tags ) && !is_wp_error( $tags ) ): ?>
    <?php foreach ( $tags as $tag ): ?>
     <?php echo '<a href="'.get_tag_link($tag->term_id).'" title="'.$tag->name.'" rel="tag">'.$tag->name.'</a>';?>
        <?php endforeach; ?>
    <?php endif; ?>
3
  • To clarify using your example, you want to find tags that have both of these words (or all 3)? Like "foo student bar worker" but not "foo student". get_terms/get_tags is no use for this and you'd have to write a custom query
    – kero
    Commented Feb 7, 2018 at 12:31
  • @kero I want to find tags that have all of these 3 words
    – bpy
    Commented Feb 7, 2018 at 12:47
  • So a tag like group worker student, but not worker student? Or tags like big worker but not small person? Commented Feb 7, 2018 at 13:01

1 Answer 1

2

You can't use multiple arguments of the same name. You've passed 3 name__like arguments. This isn't going to work the way you expect.

Arguments that support multiple possible values will accept an Array, but name__like is not one of those arguments. name__like can only be a String.

The value passed to name like is passed into the SQL like this in WP_Term_Query::get_terms():

$this->sql_clauses['where']['name__like'] = $wpdb->prepare( "t.name LIKE %s", '%' . $wpdb->esc_like( $args['name__like'] ) . '%' );

So the value passed there is put directly into t.name LIKE %(here)%. But it's also excaped, so you can't use something like this (I tried):

'name__like' => 'worker% OR t.name LIKE %group'

The closest thing WP_Term_Query supports is multiple names:

'name' => ['worker', 'student', 'group']

But that will only match terms that are exactly worker, student or group.

To do what you're after will either require doing 3 separate calls to get_tags() or get_terms() with different values for name__like, or doing the query manually with $wpdb:

global $wpdb;

$results = $wpdb->get_results(
    "SELECT
        t.*, tt.*
    FROM
        wp_terms AS t
    INNER JOIN
        wp_term_taxonomy AS tt ON
            t.term_id = tt.term_id
    WHERE
        tt.taxonomy = 'post_tag' AND 
        (
            t.name LIKE '%worker%' OR
            t.name LIKE '%group%' OR
            t.name LIKE '%student%'
        )
    ORDER BY
        t.name ASC"
);

if ( ! empty( $results ) ) {
    $tags = array_map( 'get_term', $results ); // Turn each result into a proper WP_Term object.

    foreach ( $tags as $tag ) {
        echo $tag->name;
    }
}

Note that if those particular words are dynamic, you'll need to prepare the query with $wpdb->prepare().

2
  • Two things: 1- This is not exact because is also getting tags like "grouped", and 2- What do you mean by "...if those particular words are dynamic..."?
    – bpy
    Commented Feb 7, 2018 at 13:35
  • name__like would've had that issue to. You're going to need a custom query, but you'll probably need to use regex. Is there a reason you're doing it this way? Maybe some sort of meta that's applied to tags would work better. Will certainly be easier to query. Commented Feb 7, 2018 at 13:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.