J'essaie de personnaliser les résultats de la recherche pour une recherche générique, mais seulement s'il utilise le modèle search.php
. J'ai d'autres recherches sur mon site et je ne veux pas que ce filtre interfère avec elles. Tout fonctionne sur le code suivant, à l'exception de is_page_template('search.php')
.
Une fois que j'entre cette ligne de code en tant que condition, il revient simplement au filtrage de recherche normal, car ma condition IF échoue. Comment puis-je exécuter mon code uniquement si nous sommes sur la page search.php
?
//Filter the search for only posts and parts
function SearchFilter($query)
{
if ($query->is_search && is_page_template('search')) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_filter('pre_get_posts', 'SearchFilter');
Il existe une solution de contournement qui pourrait vous coûter une requête supplémentaire. Cependant, @Milo a déjà mentionné que WordPress est assez intelligent pour mettre en cache les requêtes, cela ne devrait donc pas être un gros problème pour vous.
Vous pouvez exécuter la requête à l'intérieur du pre_get_posts
, puis effectuer quelques vérifications. Si la situation correspond à vos besoins, filtrez la requête:
//Filter the search for only posts and parts
function SearchFilter($query)
{
remove_action('pre_get_posts', 'SearchFilter');
// Run the query to fetch the results
$posts = get_posts( $query->query );
if(!empty($posts)) {
// Check the template for the first post
if( get_page_template_slug( $posts[0]->ID ) == 'YOUR SLUG HERE' ){
$search_template = true;
} else {
$search_template = false;
}
}
// Now filter the posts
if ($query->is_main_query() & $query->is_search && $search_template) {
$query->set('post_type', array('post', 'parts'));
$query->set('meta_key', 'Manufacturer');
$query->set('orderby', 'meta_value');
$query->set('order', 'ASC');
}
return $query;
}
add_action('pre_get_posts', 'SearchFilter');
Permet de le décomposer étape par étape:
if ($query->is_search && is_page_template('search')) {
Il y a 3 problèmes ici
is_page_template
search.php
n'est pas un modèle de page, ce n'est pas ainsi que le modèle de recherche est chargé. Donc ça ne marchera pas.
Mais si cela a fonctionné, il y a un nouveau problème. Des fonctions telles que is_page_template
etc reposent sur la requête principale, mais nous sommes dans un filtre pre_get_posts
, vous ne savez pas si cette requête a déjà été définie, ou si vous filtrez cette requête ou une autre.
Nous devons donc:
is_page_template
, il ne fait pas ce que vous pensez qu'il fait$query->is_main_query()
afin que le filtre n'interfère pas avec les widgets et les autres requêtesif ($query->is_search
Cela ne fonctionne pas et devrait générer PHP avertissements pour vous. Le problème est que is_search
est une fonction/méthode et non une variable, ce devrait être:
if ( $query->is_search() && $query->is_main_query() ) {
search.php
?WordPress décide quel modèle est chargé en fonction de la requête principale. S'il s'agit de la requête principale et que is_search
est vrai, alors search.php
sera chargé.
Pour cette raison, WordPress n'a pas encore décidé quel modèle utiliser lorsque votre filtre est activé. En fait, vous pouvez faire en sorte que WordPress modifie le modèle qu’il charge en modifiant les variables de la requête. Par exemple, si vous supprimez toutes les variables et que vous leur indiquez de charger un seul message, vous n'obtiendrez pas search.php
, ni d'archive, mais plutôt single.php
.
is_main_query
sera faux, donc pas un problème