J'utilise cette fonction pour insérer au début de la boucle deux messages à ma convenance (avec clé méta et valeur)
add_filter( 'posts_results', 'insert_post_wpse_96347', 10, 2 );
function insert_post_wpse_96347( $posts, \WP_Query $q ) {
remove_filter( current_filter(), __FUNCTION__ );
if ( $q->is_main_query() && $q->is_home() && 0 == get_query_var( 'paged' ) ) {
$args = [
'meta_key' => 'caja',
'meta_value' => ['uno','dos'],
'post__not_in' => get_option( "sticky_posts" ),
'posts_per_page' => '2',
'suppress_filters' => true
];
$p2insert = new WP_Query($args);
$insert_at = 0;
if ( !empty( $p2insert->posts ) ) {
array_splice( $posts, $insert_at, 0, $p2insert->posts );
}
}
return $posts;
}
Mais ces messages apparaissent toujours dans la boucle, ils devraient se cacher pour ne pas regarder deux fois.
Comment puis-je faire ceci?
Nous pouvons essayer la méthode alternative suivante:
Supprimez les deux publications sélectionnées via notre requête personnalisée de la requête principale via l'action pre_get_posts
Renvoie les deux articles en haut de la première page via le filtre the_posts
Regardons le code possible:
add_action( 'pre_get_posts', function ( $q )
{
remove_filter( current_filter(), __FUNCTION__ );
if ( $q->is_home() // Only target the home page
&& $q->is_main_query() // Only target the main query
) {
// Set our query args and run our query to get the required post ID's
$args = [
'meta_key' => 'caja',
'meta_value' => ['uno','dos'],
'posts_per_page' => '2',
'fields' => 'ids', // Get only post ID's
];
$ids = get_posts( $args );
// Make sure we have ID's, if not, bail
if ( !$ids )
return;
// We have id's, lets remove them from the main query
$q->set( 'post__not_in', $ids );
// Lets add the two posts in front on page one
if ( $q->is_paged() )
return;
add_filter( 'the_posts', function ( $posts, $q ) use ( $args )
{
if ( !$q->is_main_query() )
return $posts;
// Lets run our query to get the posts to add
$args['fields'] = 'all';
$posts_to_add = get_posts( $args );
$stickies = get_option( 'sticky_posts' );
if ( $stickies ) {
$sticky_count = count( $stickies );
array_splice( $posts, $sticky_count, 0, $posts_to_add );
return $posts;
}
// Add these two posts in front
$posts = array_merge( $posts_to_add, $posts );
return $posts;
}, 10, 2 );
}
});
Cela devrait remplacer le code actuel que vous avez posté dans votre question
Essayez ceci à la place:
REMARQUE: veillez à ajouter toute logique conditionnelle supplémentaire dont vous avez besoin pour votre cas d'utilisation, telle qu'une vérification de is_home()
et la valeur de get_query_var( 'paged' )
. J'ai volontairement laissé ceux-ci pour plus de concision.
function custom_pre_get_posts_meta_query( $query ) {
if ( is_admin() || ! $query->is_main_query() )
return;
$meta_key = 'caja'; //meta_key to query
$query->set(
'orderby',
array(
'meta_value' => 'DESC',
'date' => 'DESC'
)
);
$query->set(
'meta_query',
array(
array(
'key' => $meta_key,
'value' => 'IGNORE THIS VALUE', //this just needs to be something random
'compare' => 'NOT EXISTS'
)
)
);
add_filter( 'posts_where', 'custom_where_meta_query' );
}
add_action( 'pre_get_posts', 'custom_pre_get_posts_meta_query', 1 );
function custom_where_meta_query( $where = '' ){
global $wpdb;
$meta_key = 'caja'; //meta_key
$meta_values = array('uno', 'dos'); //meta_values
$sql = "'" . implode( "', '", array_map( 'esc_sql', $meta_values ) ) . "'";
$where .= $wpdb->prepare(
" OR (( {$wpdb->postmeta}.meta_key = %s AND {$wpdb->postmeta}.meta_value IN ( {$sql} ) ))",
$meta_key
);
remove_filter( 'posts_where', 'custom_where_meta_query' );
return $where;
}
La première fonction de rappel sur pre_get_posts
lancera WP_Meta_Query
, qui crée le code SQL nécessaire que nous filtrons ensuite dans la deuxième fonction de rappel.
Les résultats sont d'abord classés par meta_value DESC
, puis par date DESC
. Cela regroupera les deux messages correspondants pour la clé méta caja
en haut et les messages restants seront triés par date par la suite.
Cela vous évite d'avoir à interroger de nouveau la base de données pour deux publications spécifiques, puis de fusionner le jeu de résultats et enfin de purger le jeu de résultats des doublons.