Crear un formulario de búsqueda para campos personalizados

11

He creado un tema para un concesionario de automóviles. Cada automóvil es un tipo de publicación personalizado ("vehículo") y tiene alrededor de 12 campos personalizados con elementos como Marca, Modelo, Kilometraje, Tipo de combustible, etc.

Básicamente, en la página de inicio, quiero un formulario de búsqueda que tenga listas desplegables para Marca y modelo y que contenga todas las Marcas o Modelos disponibles.

También quiero que tenga 2 opciones para Año, para que el usuario final pueda seleccionar "2006" y "2012" y los resultados de búsqueda contengan todos los vehículos con el año entre esos dos números.

¿Hay algún complemento que pueda hacer esto?

Gracias por cualquier ayuda ... esto me ha estado volviendo loco por horas !!!!

absdigital
fuente
Creo que puedes usar este complemento para ayudarte a mejorar wordpress.org/plugins/wp-custom-fields-search
DINESH BHIMANI
Gracias ... Pero eso no explica cómo crear realmente el formulario de búsqueda. Quiero decir que puedo programar el formulario en HTML, pero ¿cómo hago para que funcione?
absdigital

Respuestas:

16

______ ACTUALIZACIÓN_______
Aunque obtengo más y más votos, y la solución funciona, pero la respuesta de cybmeta es en realidad la respuesta que es agradable y la forma de WordPress. Definitivamente deberías probar eso.

Paso 1

Comience por hacer un Formulario de búsqueda avanzada con el que desea que su usuario interactúe con el sitio web y lo guarde con un nombre (es decir, lo guardé como advanced-searchform.php, pero no lo guarde con, searchform.phpluego reemplazará el formulario de búsqueda predeterminado de WordPress ):

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

Luego llame al formulario a su plantilla de la siguiente manera:

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

Ahora su formulario de búsqueda está listo, y ahora puede usar el formulario de búsqueda y puede tomar la entrada del usuario en la URL.

Paso 2

Lo que solo necesita es: consultar la base de datos y consultar el tipo de publicación y sus campos personalizados según la consulta de búsqueda . Recuerde que su consulta de búsqueda ahora es la URL que obtuvo después de enviar el formulario. Ahora solicite a WordPress que cargue su página de resultados de búsqueda personalizada cuando se envíe el formulario. Coloque la siguiente función en su functions.phppara que habilite su plantilla de búsqueda personalizada en lugar de la predeterminada search.php:

<?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');
?>

Traje el código en algún lugar de WPSE (olvidé la raíz), pero hay controversia al usar el código anterior. Pero en realidad funciona ( excusa poco convincente, por supuesto ).

Verifique otra forma @GM sugerido.

Paso 3

Crea un nuevo archivo y guárdalo con advanced-search-result.php(porque usamos este nombre functions.php) y ahora eres libre, obviamente. El concepto es:

  • Agarra los datos de la URL,
  • Use un simple WP_Query()(si su consulta es compleja, use una $wpdbconsulta),
  • Pase los comandos dentro de la consulta, obtenga datos de db y
  • Mostrar el resultado [s]

Una muestra puede ser:

<?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();
?>

Entonces, aquí está tu última cosa. Pero aún hay muchos desafíos:

  • Valores alternativos : se puede realizar una búsqueda avanzada con TODOS los campos o CUALQUIERA de los campos, por lo que debe asegurarse de que la Consulta tome todos los resultados según la búsqueda y los datos. Puede usar $wpdbconsultas SQL personalizadas para resultados de búsqueda complejos y eso será puro MySQL: WordPress no tiene nada allí.
  • Desinfección y validación : el campo de textos y el área de texto son tan vulnerables que pueden causar malas prácticas en su sitio. Por lo tanto, pasar datos sin procesar no sería seguro, tendrá que desinfectarlos y validarlos antes de pasar a la consulta db. ( Desinfección y validación de datos con WordPress - TutsPlus )
  • Diseño : puede elegir la plantilla page.php(o search.php) y hacer esta página sobre la base de eso.

Entonces, tienes la idea, ahora es tu turno de explorar y descubrir el camino . Recuerde, el camino de todos es diferente. Haz el tuyo para que pueda seguirte. :)

Mayeenul Islam
fuente
Gracias por tomarse el tiempo, muy amable de su parte. ¿Sabes cómo puedo tenerlo para que el menú desplegable de "Marcas" muestre automáticamente cualquier marca que se haya ingresado en una de las publicaciones del vehículo?
absdigital
Me alegrará si te funciona. :)
Mayeenul Islam
¿Sabes cómo puedo tenerlo para que el menú desplegable de "Marcas" muestre automáticamente cualquier marca que se haya ingresado en una de las publicaciones del vehículo?
absdigital
use a WP_Query()usando parámetros de campo personalizados y repita el resultado para mostrar el <option>s.
Mayeenul Islam
Me gustaría ver esta "búsqueda avanzada" realizada con pre_get_postsgancho y no un bucle secundario.
cybmeta
23

Aunque la respuesta de @ MayeenulIslam podría funcionar, creo que la forma correcta de hacer una búsqueda avanzada es usar el pre_get_postsgancho de acción.

Paso 1: Formulario de búsqueda

Este paso igual al paso 1 en la otra respuesta, sólo cambió el iddel namecampo ( <input type="text" ...>utilizado para la búsqueda de "s" , por lo que se puede utilizar directamente para que el campo de búsqueda. Guardar este código en advanced-searchform.phpvirtud de su carpeta de temas. Entonces, el uso get_template_part( 'advanced', 'searchform' );de cárguelo donde quiera que aparezca en su tema:

<?php /**`advanced-searchform.php`*/ ?>
<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>

Paso 2: agregue filtros a la consulta de búsqueda

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 );

    }
}

Paso 3: plantilla (opcional)

Con este método, la plantilla de búsqueda predeterminada de WordPress se usará para filtrar los resultados sin la necesidad de una consulta secundaria. Si desea usar una plantilla diferente para la búsqueda avanzada, puede usar el template_includefiltro. Por ejemplo, si desea utilizar el advanced-search-template.phparchivo como plantilla para los resultados del formulario de búsqueda avanzada:

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;
}
cybmeta
fuente
3
Muchas gracias por la forma de WordPress. Acabo de trabajar con este y es increíble. :)
Mayeenul Islam