最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

wp query - Mixing regular and custom post types (with meta_query) on home page

programmeradmin7浏览0评论

Not sure how to achieve this. I'm trying to mix standard posts and custom posts on a site homepage but I only want to display the custom posts if a meta value is set. Displaying the posts works fine 'post_type' => array('game', 'post') but when I add in the meta_query the regular posts are no longer displaying (which makes sense as they don't meet the meta_query condition).

So how do I limit the meta_query to only the custom post type so that the regular post will still be included?

Not sure how to achieve this. I'm trying to mix standard posts and custom posts on a site homepage but I only want to display the custom posts if a meta value is set. Displaying the posts works fine 'post_type' => array('game', 'post') but when I add in the meta_query the regular posts are no longer displaying (which makes sense as they don't meet the meta_query condition).

So how do I limit the meta_query to only the custom post type so that the regular post will still be included?

Share Improve this question edited Jan 10, 2014 at 6:46 kaiser 50.9k27 gold badges150 silver badges245 bronze badges asked Jan 10, 2014 at 5:50 lrmlrm 1034 bronze badges 1
  • 1 Good question ... +1. I think you won't be able to do that with a default WP_Query. You'll need to either use pre_get_posts alter your query or a custom SQL statement. Anyway, please show your current code. – kaiser Commented Jan 10, 2014 at 6:45
Add a comment  | 

1 Answer 1

Reset to default 4

There are different way to do the trick, 2 comes into my mind:

  1. use a complete custom $wpdb query
  2. use WP_Query with filters, using WP_Meta_Query to build the additional sql

I'll post here sample code for case #2

/**
 * Run on pre_get_posts and if on home page (look at url)
 * add posts_where, posts_join and pre_get_posts hooks
 */
function home_page_game_sql( $query ) {
  // exit if is not main query and home index
  if ( ! ( $query->is_main_query() && ! is_admin() && is_home() ) ) return;
  add_filter( 'posts_where', 'home_page_game_filter' );
  add_filter( 'posts_join', 'home_page_game_filter' );
}
add_action('pre_get_posts', 'home_page_game_sql');


/**
 * Set the SQL filtering posts_join and posts_where
 * use WP_Meta_Query to generate the additional where clause
 */
function home_page_game_filter( $sql = '' ) {
  // remove filters
  remove_filter( current_filter(), __FUNCTION__);
  static $sql_game_filters;
  if ( is_null($sql_game_filters) ) {
    // SET YOUR META QUERY ARGS HERE
    $args = array(
      array(
        'key' => 'my_custom_key',
        'value'   => 'value_your_are_looking_for',
        'compare' => '='
      )
    );
    $meta_query = new WP_Meta_Query( $args );
    $sql_game_filters = $meta_query->get_sql('post', $GLOBALS['wpdb']->posts, 'ID');
  }
  // SET YOUR CPT NAME HERE
  $cpt = 'game';
  global $wpdb;
  if ( current_filter() === 'posts_where' && isset($sql_game_filters['where']) ) {
    $where = "AND ($wpdb->posts.post_status = 'publish') ";
    $where .= "AND ( $wpdb->posts.post_type = 'post' OR ( ";
    $where .= $wpdb->prepare( "$wpdb->posts.post_type = %s", $cpt);
    $where .= $sql_game_filters['where'] . ' ) )';
    $where .= " GROUP BY $wpdb->posts.ID ";
    return $where;
  }
  if ( current_filter() === 'posts_join' && isset($sql_game_filters['join']) ) {
    return $sql .= $sql_game_filters['join'];
  }
}

See inline comments for further explaination.

Also look at WP_Meta_Query on Codex for complete docs on how to set your meta query args.


Edit

I refactored code in a reusable plugin, using a class. Available as Gist.

发布评论

评论列表(0)

  1. 暂无评论