web-dev-qa-db-fra.com

La bonne façon de créer une page de recherche personnalisée pour des types d'article complexes complexes

J'essaie de créer une page de recherche personnalisée pour afficher uniquement les types de publications personnalisées répondant à des critères de recherche spécifiques. J'ai un formulaire complexe qui implique différentes sélections, boutons radio et champs de saisie de texte. Je suis à l'aise avec la classe WP_Query pour interroger les publications identifiées via le formulaire de recherche, mais je ne suis pas sûr de devoir créer des modèles supplémentaires ou d'utiliser la page de recherche intégrée.

Laissez-moi vous donner un exemple pour aider à communiquer mon énigme. Imaginez que vous avez la "personne" du CPT. Pour chaque personne, vous avez "Date de naissance", "Sexe", "Taille" et "Poids". Vous voulez rechercher tous les mâles nés après 1972, qui sont plus grands que 6 pieds de haut. Comment travailleriez-vous cette recherche? Encore une fois, je peux facilement réunir $args pour que la classe WP_Query reçoive ces publications. J'ai besoin de connaître le meilleur moyen d'intégrer cela avec WordPress.

En fin de compte, j’ai besoin d’une solution qui réponde aux exigences suivantes:

1) Préserve la pagination sur la page de recherche 2) Ne recherche que le CPT spécifique, pas les autres CPT

Et j'ai les questions suivantes

1) Devrais-je avoir un modèle séparé pour cela, ou puis-je l’intégrer directement avec search.php? Ma solution actuelle semble hacky et je voudrais développer une alternative. J'ai créé une nouvelle page dans WP admin. J'utilise l'URL de cette page comme attribut action dans le formulaire de recherche. J'utilise ensuite un modèle personnalisé pour afficher les résultats de cette page. Cela me semble faux.

2) Si j'intègre ceci avec search.php, comment puis-je conserver les résultats de recherche habituels, en plus de ces résultats de recherche personnalisés?

Je vous remercie beaucoup pour votre aide!

EDIT: Après une enquête plus approfondie, je commence à penser que pre_get_posts sera probablement impliqué dans une "meilleure façon" de procéder.

4
tollmanz

J'ai trouvé un moyen de faire ce travail. J'avais raison de penser que pre_get_posts était la voie à suivre. Tout d'abord, j'ai ajouté une action:

// Filter the search page
add_filter('pre_get_posts', 'search_pre_get_posts');

Puis j'ai ajouté la fonction. Cette fonction vérifie d’abord que le contexte est correct. Dans mon formulaire de recherche personnalisé, j'utilise un nonce. Le nonce m'aide à vérifier que c'est ma recherche personnalisée en cours d'exécution, et non la recherche intégrée. Je manipule ensuite les variables de requête qui seront envoyées à la requête. Je montre ici ma fonction complète, qui inclut toute la validation et la désinfection des variables, ainsi que la façon dont la requête est manipulée:

/**
 * Filters for search of events
 *
 * When a search is initiated, this filter will check to see if it is an
 * event search. If so, it will process the search data associated with
 * event searches and add it to the $query object prior to it being used
 * to query the database.
 *
 * @param $query The query object generated for this page
 * @return void
 */
function search_pre_get_posts($query)
{
    // Verify that we are on the search page that that this came from the event search form
    if($query->query_vars['s'] != '' && is_search() && isset($_GET['prefix-submitted']) && $_GET['prefix-submitted'] && wp_verify_nonce($_GET['prefix-search-nonce'], 'prefix-search'))
    {
        // Always order by date
        $query->set('orderby', 'meta_value');
        $query->set('order', 'ASC');
        $query->set('meta_key', '_datetime-from');

        // Set the text string for the search
        $clean_text = (isset($_GET['prefix-text'])) ? wp_strip_all_tags($_GET['prefix-text']) : '';
        $query->set('s', $clean_text);

        // Validate dates
        $clean_from = (isset($_GET['prefix-from'])) ? $this->handle_date($_GET['prefix-from']) : false;
        $clean_to = (isset($_GET['prefix-to'])) ? $this->handle_date($_GET['prefix-to']) : false;

        // Validate taxonomies
        $clean_type = (isset($_GET['prefix-type'])) ? $this->handle_taxonomy_id($_GET['prefix-type'], 'prefix-type') : false;
        $clean_location = (isset($_GET['prefix-location'])) ? $this->handle_taxonomy_id($_GET['prefix-location'], 'prefix-location') : false;

        // Build meta_query variable based on date pieces
        if($clean_from && $clean_to)
        {
            $meta_query = array(
                array(
                    'key' => '_datetime-from',
                    'value' => array($clean_from, $clean_to),
                    'compare' => 'BETWEEN',
                    'type' => 'DATE'
                )
            );
        }
        elseif($clean_from)
        {
            $meta_query = array(
                array(
                    'key' => '_datetime-from',
                    'value' => $clean_from,
                    'compare' => '>=',
                    'type' => 'DATE'
                )
            );
        }
        elseif($clean_to)
        {
            $meta_query = array(
                array(
                    'key' => '_datetime-from',
                    'value' => $clean_from,
                    'compare' => '>=',
                    'type' => 'DATE'
                )
            );
        }
        else
            $meta_query = '';

        // Set the meta query
        $query->set('meta_query', $meta_query);

        // Build tax query based on taxonomy pieces
        if($clean_type && $clean_location)
        {
            $tax_query = array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'prefix-type',
                    'field' => 'id',
                    'terms' => $clean_type,
                    'operator' => 'IN'
                ),
                array(
                    'taxonomy' => 'prefix-location',
                    'field' => 'id',
                    'terms' => $clean_location,
                    'operator' => 'IN'
                )
            );
        }
        elseif($clean_type)
        {
            $tax_query = array(
                array(
                    'taxonomy' => 'prefix-type',
                    'field' => 'id',
                    'terms' => $clean_type,
                    'operator' => 'IN'
                )
            );
        }
        elseif($clean_location)
        {
            $tax_query = array(
                array(
                    'taxonomy' => 'prefix-location',
                    'field' => 'id',
                    'terms' => $clean_location,
                    'operator' => 'IN'
                )
            );
        }
        else
            $tax_query = '';

        // Set the tax query
        $query->set('tax_query', $tax_query);
    }
}
3
tollmanz