web-dev-qa-db-fra.com

Création d'un formulaire de recherche pour les champs personnalisés

J'ai construit un thème pour un concessionnaire automobile. Chaque voiture est un type de poste personnalisé ("véhicule") et comporte environ 12 champs personnalisés avec des éléments tels que Marque, Modèle, Kilométrage, Type de carburant, etc.

Donc, fondamentalement, sur la page d’accueil, je veux un formulaire de recherche qui contient des listes déroulantes Marque et Modèle et contient toutes les marques ou modèles disponibles.

Je souhaite également deux options pour l'année, afin que l'utilisateur final puisse sélectionner "2006" et "2012". Les résultats de la recherche contiennent tous les véhicules dont l'année se situe entre ces deux chiffres.

Y at-il un plugin là-bas qui peut faire cela?

Merci pour toute aide .. cela m'a rendu fou pendant des heures !!!!

11
absdigital

_____UPDATE______
Bien que je reçoive de plus en plus de votes et que la solution fonctionne, mais la réponse de cybmeta est en fait la réponse qui est à la manière de Nice et WordPress. Vous devriez certainement essayer ça.

Étape 1

Commencez par créer un formulaire de recherche avancée avec lequel vous voulez que votre utilisateur interagisse avec le site Web, et enregistrez-le avec un nom (c'est-à-dire que je l'ai enregistré en tant que advanced-searchform.php - mais ne l'enregistrez pas avec searchform.php, il remplacera le nom par défaut de WordPress. formulaire de recherche):

<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">

    <h3><?php _e( 'Advanced Search', 'textdomain' ); ?></h3>

    <!-- PASSING THIS TO TRIGGER THE ADVANCED SEARCH RESULT PAGE FROM functions.php -->
    <input type="hidden" name="search" value="advanced">

    <label for="name" class=""><?php _e( 'Name: ', 'textdomain' ); ?></label><br>
    <input type="text" value="" placeholder="<?php _e( 'Type the Car Name', 'textdomain' ); ?>" name="name" id="name" />

    <label for="model" class=""><?php _e( 'Select a Model: ', 'textdomain' ); ?></label><br>
    <select name="model" id="model">
        <option value=""><?php _e( 'Select one...', 'textdomain' ); ?></option>
        <option value="model1"><?php _e( 'Model 1', 'textdomain' ); ?></option>
        <option value="model2"><?php _e( 'Model 1', 'textdomain' ); ?></option>
    </select>

    <input type="submit" id="searchsubmit" value="Search" />

</form>

Appelez ensuite le formulaire dans votre modèle comme suit:

<?php get_template_part( 'advanced', 'searchform' ); ?>

Votre formulaire de recherche est maintenant prêt. Vous pouvez maintenant utiliser le formulaire de recherche et enregistrer les entrées de l'utilisateur dans l'URL.

Étape 2

Ce qu'il vous faut simplement: interroger la base de données et interroger le type d'article et ses champs personnalisés selon la requête de recherche. N'oubliez pas que votre requête de recherche est maintenant l'URL que vous avez obtenue après la soumission du formulaire. Maintenant, demandez à WordPress de charger votre page de résultat de recherche personnalisée lorsque le formulaire est soumis. Placez la fonction suivante dans votre functions.php afin qu'il active votre modèle de recherche personnalisé au lieu du search.php par défaut:

<?php
function wpse_load_custom_search_template(){
    if( isset($_REQUEST['search']) == 'advanced' ) {
        require('advanced-search-result.php');
        die();
    }
}
add_action('init','wpse_load_custom_search_template');
?>

J'ai apporté le code quelque part de WPSE (j'ai oublié la racine), mais l'utilisation du code ci-dessus suscite une controverse. Mais cela fonctionne réellement (excuse boiteuse bien sûr).

Vérifiez d'une autre manière @ G.M. suggéré.

Étape 3

Créez un nouveau fichier et enregistrez-le avec advanced-search-result.php (car nous avons utilisé ce nom dans functions.php) et maintenant vous êtes libre - évidemment. Le concept est:

  • Prenez les données de l'URL,
  • Utilisez une simple WP_Query() (si votre requête est complexe, utilisez la requête $wpdb),
  • Passez les commandes dans la requête, récupérez les données de la base de données, et
  • Afficher le résultat [s]

Un échantillon peut être:

<?php
// Get data from URL into variables
$_name = $_GET['name'] != '' ? $_GET['name'] : '';
$_model = $_GET['model'] != '' ? $_GET['model'] : '';

// Start the Query
$v_args = array(
        'post_type'     =>  'vehicle', // your CPT
        's'             =>  $_name, // looks into everything with the keyword from your 'name field'
        'meta_query'    =>  array(
                                array(
                                    'key'     => 'car_model', // assumed your meta_key is 'car_model'
                                    'value'   => $_model,
                                    'compare' => 'LIKE', // finds models that matches 'model' from the select field
                                ),
                            )
    );
$vehicleSearchQuery = new WP_Query( $v_args );

// Open this line to Debug what's query WP has just run
// var_dump($vehicleSearchQuery->request);

// Show the results
if( $vehicleSearchQuery->have_posts() ) :
    while( $vehicleSearchQuery->have_posts() ) : $vehicleSearchQuery->the_post();
        the_title(); // Assumed your cars' names are stored as a CPT post title
    endwhile;
else :
    _e( 'Sorry, nothing matched your search criteria', 'textdomain' );
endif;
wp_reset_postdata();
?>

Alors, voici votre dernière chose. Mais il reste encore de nombreux défis à relever:

  • Valeurs alternatives - une recherche avancée peut être effectuée avecTOUSdes champs ouTOUTdu champ, vous devez donc vous assurer que la requête prend tous les résultats selon la recherche et les données. Vous pouvez utiliser la requête SQL personnalisée $wpdb pour les résultats de recherche complexes, ce qui sera purement MySQL - WordPress n’y trouve rien.
  • Sanitization & Validation - le champ de texte et textarea sont si vulnérables qu’ils peuvent entraîner de mauvaises pratiques sur votre site. Donc, transmettre des données brutes serait dangereux, vous devrez les assainir et les valider avant de passer à la requête de base de données. ( Sanitization et validation des données avec WordPress - TutsPlus )
  • Conception - vous pouvez choisir le modèle page.php (ou search.php) et créer cette page sur cette base.

Alors, vous avez eu l’idée, c’est à votre tour d’explorer et de découvrir le chemin. Rappelez-vous, la manière de chacun est différente. Faites le vôtre pour que je puisse vous suivre. :)

15
Mayeenul Islam

Bien que la réponse de @ MayeenulIslam puisse fonctionner, je pense que la bonne façon de faire une recherche avancée consiste à utiliser le hook d'action pre_get_posts.

Étape 1: formulaire de recherche

Cette étape égale à l’étape 1 de l’autre réponse vient de remplacer l’identifiant du "nom" utilisé pour la recherche par "s", de sorte qu’il sera utilisé directement comme champ de recherche. Enregistrez ce code dans searchform-advanced.php sous votre dossier de thèmes. Ensuite, utilisez get_template_part( 'advanced', 'searchform' ); pour le charger à l'endroit où vous souhaitez qu'il apparaisse dans votre thème:

<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">

    <h3><?php _e( 'Advanced Search', 'textdomain' ); ?></h3>

    <!-- PASSING THIS TO TRIGGER THE ADVANCED SEARCH RESULT PAGE FROM functions.php -->
    <input type="hidden" name="search" value="advanced">

    <label for="s" class=""><?php _e( 'Name: ', 'textdomain' ); ?></label><br>
    <input type="text" value="" placeholder="<?php _e( 'Type the Car Name', 'textdomain' ); ?>" name="s" id="name" />

    <label for="model" class=""><?php _e( 'Select a Model: ', 'textdomain' ); ?></label><br>
    <select name="model" id="model">
        <option value=""><?php _e( 'Select one...', 'textdomain' ); ?></option>
        <option value="model1"><?php _e( 'Model 1', 'textdomain' ); ?></option>
        <option value="model2"><?php _e( 'Model 2', 'textdomain' ); ?></option>
    </select>

    <input type="submit" id="searchsubmit" value="Search" />

</form>

Étape 2: ajouter des filtres à la requête de recherche

add_action( 'pre_get_posts', 'advanced_search_query' );
function advanced_search_query( $query ) {

    if ( isset( $_REQUEST['search'] ) && $_REQUEST['search'] == 'advanced' && ! is_admin() && $query->is_search && $query->is_main_query() ) {

        $query->set( 'post_type', 'vehicle' );

        $_model = $_GET['model'] != '' ? $_GET['model'] : '';

        $meta_query = array(
                            array(
                                'key'     => 'car_model', // assumed your meta_key is 'car_model'
                                'value'   => $_model,
                                'compare' => 'LIKE', // finds models that matches 'model' from the select field
                            )
                        )
        );
        $query->set( 'meta_query', $meta_query );

    }
}

Étape 3: Modèles (facultatif)

Avec cette méthode, le modèle de recherche par défaut de WordPress sera utilisé pour filtrer les résultats sans recourir à une requête secondaire. Si vous souhaitez utiliser un autre modèle pour la recherche avancée, vous pouvez utiliser le filtre template_include. Par exemple, si vous souhaitez utiliser le fichier advanced-search-template.php comme modèle pour les résultats du formulaire de recherche avancée:

add_action('template_include', 'advanced_search_template');
function advanced_search_template( $template ) {
  if ( isset( $_REQUEST['search'] ) && $_REQUEST['search'] == 'advanced' && is_search() ) {
     $t = locate_template('advanced-search-template.php');
     if ( ! empty($t) ) {
         $template = $t;
     }
  }
  return $template;
}
18
cybmeta