Mezclando tipos de publicaciones regulares y personalizadas (con meta_query) en la página de inicio

9

No estoy seguro de cómo lograr esto. Estoy tratando de mezclar publicaciones estándar y publicaciones personalizadas en la página de inicio de un sitio, pero solo quiero mostrar las publicaciones personalizadas si se establece un metavalor. Mostrar las publicaciones funciona bien, 'post_type' => array('game', 'post')pero cuando agrego el meta_query, las publicaciones normales ya no se muestran (lo que tiene sentido ya que no cumplen con la condición meta_query).

Entonces, ¿cómo limito el meta_query solo al tipo de publicación personalizada para que la publicación regular todavía se incluya?

lrm
fuente
1
Buena pregunta ... +1. Creo que no podrás hacerlo con un valor predeterminado WP_Query. Deberá usar pre_get_postsalterar su consulta o una instrucción SQL personalizada. De todos modos, muestre su código actual.
kaiser

Respuestas:

4

Hay diferentes maneras de hacer el truco, 2 me viene a la mente:

  1. usar una $wpdbconsulta personalizada completa
  2. usar WP_Querycon filtros, usar WP_Meta_Querypara construir el sql adicional

Publicaré aquí el código de muestra para el caso # 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'];
  }
}

Ver comentarios en línea para más explicaciones.

También mire WP_Meta_Query en Codex para obtener documentos completos sobre cómo configurar sus argumentos de metaconsulta .


Editar

Refactoré el código en un complemento reutilizable, usando una clase. Disponible como Gist .

gmazzap
fuente
1
Funcionó perfectamente y gracias por los comentarios en línea. Simplemente copié el código en mi plugin utils.php, puse los valores apropiados en los argumentos de metaconsulta para los que proporcionó los talones, actualicé la página de inicio y allí estaban mis publicaciones y publicaciones del juego en toda su gloria. Gracias de nuevo.
lrm