meta_query with multiple values

Expanding a bit on the answer from @dgarceran

Generally, using the WP_Query class is probably a good idea for querying posts.

We’ll want to pass arguments to that query.

In your case we’ll likely want use one of the following:

  1. Custom Field Parameters” – meta_query
  2. Taxonomy Parameters” – tax_query

For a nearly comprehensive example of all the options I like to reference this gist: https://gist.github.com/luetkemj/2023628.

Also see the Codex: https://codex.wordpress.org/Class_Reference/WP_Query

Both take an array of associative arrays e.g.

Note: I’ll be using syntax that is compatible with as of PHP 5.4

    $meta_query_args = [
        [
            'key'     => 'season',
            'value'   => [ '2015', '2016' ],
            'compare' => 'IN',
        ],
    ];

We can bring those arguments into our instance of WP_Query

    $args = [
        'post_type'      => 'player',
        'posts_per_page' => 100, // Set this to a reasonable limit
        'meta_query'     => $meta_query_args,

    ];

    $the_query = new WP_Query( $args );

What’s happenning at this point is WordPress is going to check all posts that match your custom post type player. Then, it will query the metadata you’ve set with key season. Any posts matching 2015 or 2016 will be returned.

Note: using meta_query this way isn’t generally recommended because it’s a little heavy on the database. The consensus seems to be that querying taxonomies is more performant (don’t quote me on that, couldn’t find my source)

So for a quick alternative, I reccomend the following example:

    $tax_query_args = [
        [
            'taxonomy' => 'season',
            'field'    => 'slug',
            'terms'    => [ '2015', '2016' ],
            'operator' => 'IN',
        ],
    ];

    $args = [
        'post_type'      => 'player',
        'posts_per_page' => 100, // Set this to a reasonable limit
        'tax_query'      => $tax_query_args,
    ];

    $the_query = new WP_Query( $args );

Now we can actually loop through the data, here’s some example markup:

        <section class="season-list">
            <?php while ( $the_query->have_posts() ) : $the_query->the_post();
                $post_id = get_the_ID();
                // $season  = get_post_meta( $post_id, 'season', true ); // example if you are still going to use post meta
                $season = wp_get_object_terms( $post_id, 'season', [ 'fields' => 'names' ] );
                ?>

                <h3><?php the_title(); ?></h3>
                <p><?php echo __( 'Season: ' ) . sanitize_text_field( implode( $season ) ); ?></p>

            <?php endwhile; ?>
        </section>

When you use WP_Query especially in templates, make sure you end with wp_reset_postdata();

Putting it altogether (tl;dr)

    $tax_query_args = [
        [
            'taxonomy' => 'season',
            'field'    => 'slug',
            'terms'    => [ '2015', '2016' ],
            'operator' => 'IN',
        ],
    ];

    $args = [
        'post_type'      => 'player',
        'posts_per_page' => 100, // Set this to a reasonable limit
        'tax_query'      => $tax_query_args,
    ];

    $the_query = new WP_Query( $args );

    ?>
        <section class="season-list">
            <?php while ( $the_query->have_posts() ) : $the_query->the_post();
                $post_id = get_the_ID();
                // $season  = get_post_meta( $post_id, 'season', true ); // example if you are still going to use post meta
                $season = wp_get_object_terms( $post_id, 'season', [ 'fields' => 'names' ] );
                ?>

                <h3><?php the_title(); ?></h3>
                <p><?php echo __( 'Season: ' ) . sanitize_text_field( implode( $season ) ); ?></p>

            <?php endwhile; ?>
        </section>
    <?php

    wp_reset_postdata();

Front-end view of our query:
Example Front End
Dashboard view of CPT Player posts:
Example CPT Player posts

Hope that provides a bit of context πŸ‘πŸ»

Leave a Comment