web-dev-qa-db-fra.com

Filtrer la requête UNIQUEMENT pour la page de résultats de recherche

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');
2
Jordan Carter

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');
1
Jack Johansson

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:

  • supprime la vérification is_page_template, il ne fait pas ce que vous pensez qu'il fait
  • Ajouter une vérification $query->is_main_query() afin que le filtre n'interfère pas avec les widgets et les autres requêtes

Méthodes vs variables membres

if ($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() ) {

Mais 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.

Qu'en est-il des requêtes de recherche dans les modèles de page?

is_main_query sera faux, donc pas un problème

1
Tom J Nowell