Sur la page de résultats de recherche (search.php
), j'aimerais effectuer un WP_Query
supplémentaire pour conserver un ordre spécifique de types de résultats de recherche, par exemple. les résultats de recherche des auteurs doivent toujours être affichés avant les autres résultats -
Les premières pages doivent contenir les résultats de l'auteur, les autres résultats doivent être affichés uniquement sur les pages suivantes (non mélangées sur chaque page).
global $wp_query; //holds the results of the initial search query
$authorposts = $wp_query->posts;
$query = new WP_Query( 'year=2012&monthnum=12&day=12' );
$otherposts = $query->posts;
$wp_query->posts = array_merge( $authorposts, $otherposts );
$wp_query->post_count = count( $wp_query->posts );
if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
//show results loop...
Les problèmes apparaissent avec le comportement de la pagination - alors que le $authorposts
semble paginer correctement, c’est-à-dire que les numéros de page corrects pour les publications d’auteurs et la pagination ne fonctionnent que comme ceux existants. Cependant, le $otherposts
apparaît en bas de chaque page, juste en dessous des publications de l'auteur. Et ils sont les mêmes sur chaque page! De plus, le nombre de pages reflète uniquement le nombre de la première requête.
J'ai également essayé de fusionner avec l'opérateur plus
:
$wp_query->posts = $authorposts + $otherposts;
mais dans ce scénario, le $otherposts
n'apparaît pas du tout et le nombre de pages reste le même (nombre de pages pour les publications de l'auteur).
Tous les exemples ayant des objectifs similaires utilisant deux requêtes distinctes que j'ai vues se ressemblaient énormément -
Je me demande donc si la manière dont je peux étendre les résultats de la requête de recherche d'origine avec ce WP_Query
supplémentaire est suffisante ou s'il me manque des champs $wp_query
pour être remplis (correctement)? Quelle est la bonne façon de faire cela?
Mise à jour: Il est à noter que j'utilise le plug-in WP-PageNavi pour la pagination, mais que cela ne devrait pas être pertinent en premier lieu en tant que première page. est déjà rendu faux. Et il est également initialisé avec l'objet de requête: wp_pagenavi( array( 'query' => $wp_query ));
Je pense que la seule solution est de sauter la pagination SQL et de la gérer uniquement via php. Mon idée implique 2 fonctions, une accrochée à pre_get_posts
, la seconde à filtrer the_posts
.
La première fonction fait 2 choses:
paged
demandée dans la variable globale, de cette façon peut être utilisée dans la deuxième fonction qui s'exécute plus tardVoici la fonction:
function filter_my_search_query( $query ) {
if ( is_search() && $query->is_main_query() && ! is_admin() ) {
global $the_original_paged;
$the_original_paged = $query->get('paged') ? $query->get('paged') : 1;
$query->set('paged', NULL );
$query->set('nopaging', TRUE );
}
}
add_action('pre_get_posts', 'filter_my_search_query', 1);
Maintenant, la requête de recherche renvoie tous les articles, sans pagination, et le paginé requis est enregistré dans la variable globale $the_original_paged
.
Ainsi, nous pouvons filtrer the_posts
en fusionnant les publications supplémentaires souhaitées, puis obtenir uniquement les publications correctes en fonction de la page requise et des paramètres par page, et enfin réinitialiser les propriétés paged
et autres $wp_query
pour laisser le lien de pagination fonctionner:
function add_posts_to_search_query( $posts ) {
global $wp_query, $the_original_paged;
if ( ! is_main_query() || is_admin() || ! is_search() || is_null($the_original_paged) )
return $posts;
// the wanted posts per page here setted on general settings
$perpage = get_option('posts_per_page');
remove_filter( 'the_posts', 'add_posts_to_search_query' );
$new = new WP_Query( 'year=2012&monthnum=12&day=12&nopaging=1' );
$merged = array_merge( $posts, $new->posts );
$wp_query->found_posts += $new->found_posts;
// getting the right posts based on current page and posts per page
$wp_query->posts = array_slice($merged, ( $perpage * ($the_original_paged-1) ), $perpage );
// set the paged and other wp_query properties to the right value, to make pagination work
$wp_query->set('paged', $the_original_paged);
$wp_query->post_count = count($wp_query->posts);
$wp_query->max_num_pages = ceil( $wp_query->found_posts / $perpage );
unset($the_original_paged); // clean up global variable
return $wp_query->posts;
}
add_filter('the_posts', 'add_posts_to_search_query');
Filtrez la requête principale pour inclure les publications supplémentaires. Vous pouvez ajouter des paramètres de requête avec pre_get_posts
ou modifier le SQL avec posts_request
ou posts_where
.
Filtrer posts_results
ou the_posts
pour organiser les messages retournés.
function filter_posts_where($where)
{
$where .= 'OR …' /* post_date is 2012-12-12 */;
return $where;
}
function filter_the_posts($posts)
{
usort($posts, 'compare_posts');
return $posts;
}
function compare_posts($a, $b)
{
// compare "author" and dates?
if /* … */ return 1;
elseif /* … */ return -1;
else return 0;
}
Je ne pouvais pas résoudre complètement tous les problèmes impliqués dans cette question, mais pour référence, je poste l'état actuel ici:
function SQ_the_posts($posts, $q = false) {
if( is_search() && is_main_query() ){
global $wp_query;
$authorposts = $wp_query->posts;
$paged = get_query_var('paged');
remove_filter( 'the_posts', 'SQ_the_posts' );
$query = new WP_Query( 'year=2012&monthnum=12&day=12' );
add_filter( 'the_posts', 'SQ_the_posts' );
$otherposts = $query->posts;
$mergedPosts = array_merge( $authorposts, $otherposts );
$wp_query->found_posts += $query->found_posts;
$initialMaxNumPages = $wp_query->max_num_pages;
if ($paged > $initialMaxNumPages) {
$wp_query->posts = $otherposts;
$wp_query->post_count = $query->post_count;
$posts = $otherposts;
}
$wp_query->max_num_pages = ($wp_query->found_posts > 0) ? $wp_query->found_posts / 10 : 0;
$wp_query->max_num_pages += ($wp_query->found_posts % 10) ? 1 : 0;
}
return $posts;
}
add_filter( 'the_posts', 'SQ_the_posts' );
Ce que ça fait:
max_num_pages
de la première requête est dépasséCe qui ne fonctionne pas:
Je suis toujours étonné qu'il n'y ait pas d'approche facile. Au cas où quelqu'un serait capable de résoudre ces problèmes en fonction de ma réponse (copier + coller), je serais heureux de le marquer comme accepté!