WP_Query: Show post from a category OR custom field

[Revision to Use PHP Code Syntax Highlighter]

I picked up a job this week that has an interesting requirement: Show (1) the same post in multiple groupings where the filter is by a custom_field and (2) set the sort order for that post in each of those channels.

Today I’m going to show my solution to (1). It is based upon a brilliant solution to WP_Query to show post from a category OR custom field by Birgir Erlendsson.

The client currently has a custom template that retrieves posts by the value of a custom field, called “channel” on the page. The same custom field appears on every post so all that is necessary is to get the value of the page custom field and use that as the $arg value for a new WP_Query. Chris Covier has an excellent article on how that is done, Custom Loop/Query Based on Custom Fields.

The challenge is to get from Chris’s solution to Birgir’s solution and add the ability to change the $args in new WP_Query( $args ) so that we pull back posts in a custom_field grouping that does not have the same custom_field value.

I get to the solution by adding the ability to check a category on any post that is identical to the custom_field choices. This gives us the ability to have two posts

(1) with a custom_field value for interesting-stuff with a category of good-stuff and

(2) another with a custom_field value for silly-stuff with a category of interesting-stuff

so that we can get both posts in the post grouping that is based upon the “interesting-stuff” custom_field field.

I add a statement that assigns the custom_field value to the category slug and use Birgir’s solution. One of the custom fields that is two words gets concatenated for the custom field value while it gets linked by a dash as a slug so I have to use and if/else statement to account for that case.

get_header(); ?>

  <div id="primary" class="content-area">

    <main id="main" class="site-main" role="main">    

      $custom_field = get_post_custom_values('page_channel');
      $channel_value = $custom_field[0];
      echo "<h1>" . $channel_value . " is the channel value <br></h1>";

      if ($channel_value == 'careteam') {
        $cat_slug = 'care-team';
      else {
        $cat_slug = $channel_value;

      $args = [
          'post_type'    => 'post',
          '_meta_or_tax' => true,        // <-- our new custom parameter
          'tax_query' => array(
                  'taxonomy'  => 'category',
                  'field'     => 'slug',
                  'terms' => array( $cat_slug ),
                  'operator'  => 'IN'
          'meta_query'   => $custom_field,       // <-- our meta query
            'meta_query' => array(
                          'key'     => 'page_channel',
                          'value'   => array( $channel_value ),
                          'compare' => 'IN',
      $cust_posts = new WP_Query($args);
      if ($cust_posts->have_posts());
       while ($cust_posts->have_posts()) :

        <?php get_template_part( 'content', 'page' ); ?>

          // If comments are open or we have at least one comment, load up the comment template
          if ( get_theme_mod( 'sparkling_page_comments' ) == 1 ) :
            if ( comments_open() || '0' != get_comments_number() ) :

      <?php endwhile; // end of the loop. ?>

    </main><!-- #main -->

  </div><!-- #primary -->

<?php get_footer(); ?>

2 thoughts on “WP_Query: Show post from a category OR custom field

Comments are closed.