Creando un formulario de búsqueda para campos personalizados
He construido un tema para un concesionario de coches. Cada coche es un tipo de entrada personalizada ("vehicle"), y tiene aproximadamente 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 el Año, de modo 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.
¿Existe algún plugin que pueda hacer esto?
¡Gracias por cualquier ayuda... esto me está volviendo loco durante horas!

Aunque la respuesta de @MayeenulIslam podría funcionar, creo que la forma correcta de hacer una búsqueda avanzada es utilizando el gancho de acción pre_get_posts
.
Paso 1: Formulario de búsqueda
Este paso es igual al paso 1 en la otra respuesta, solo se cambió el id
del campo name
(<input type="text" ...>
) utilizado para la búsqueda a "s", para que se use directamente como campo de búsqueda.
Guarda este código en advanced-searchform.php
dentro de la carpeta de tu tema. Luego, usa get_template_part( 'advanced', 'searchform' );
para cargarlo donde quieras que aparezca en tu tema:
<?php /**`advanced-searchform.php`*/ ?>
<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<h3><?php _e( 'Búsqueda Avanzada', 'textdomain' ); ?></h3>
<!-- PASANDO ESTO PARA ACTIVAR LA PÁGINA DE RESULTADOS DE BÚSQUEDA AVANZADA DESDE functions.php -->
<input type="hidden" name="search" value="advanced">
<label for="s" class=""><?php _e( 'Nombre: ', 'textdomain' ); ?></label><br>
<input type="text" value="" placeholder="<?php _e( 'Escribe el Nombre del Coche', 'textdomain' ); ?>" name="s" id="name" />
<label for="model" class=""><?php _e( 'Selecciona un Modelo: ', 'textdomain' ); ?></label><br>
<select name="model" id="model">
<option value=""><?php _e( 'Selecciona uno...', 'textdomain' ); ?></option>
<option value="model1"><?php _e( 'Modelo 1', 'textdomain' ); ?></option>
<option value="model2"><?php _e( 'Modelo 2', 'textdomain' ); ?></option>
</select>
<input type="submit" id="searchsubmit" value="Buscar" />
</form>
Paso 2: Añadir 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', // se asume que tu meta_key es 'car_model'
'value' => $_model,
'compare' => 'LIKE', // encuentra modelos que coincidan con 'model' del campo select
)
)
);
$query->set( 'meta_query', $meta_query );
}
}
Paso 3: Plantillas (opcional)
Con este método, se usará la plantilla de búsqueda predeterminada de WordPress filtrando los resultados sin necesidad de una consulta secundaria. Si deseas usar una plantilla diferente para la búsqueda avanzada, puedes usar el filtro template_include
. Por ejemplo, si quieres usar el archivo advanced-search-template.php
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;
}

______ACTUALIZACIÓN_______
Aunque estoy recibiendo más y más votos, y la solución funciona, la respuesta de cybmeta es en realidad la respuesta correcta y la forma adecuada en WordPress. Definitivamente deberías probar eso.
Paso 1
Comienza creando un Formulario de Búsqueda Avanzada con el que tus usuarios interactuarán con el sitio web, y guárdalo con un nombre (por ejemplo, lo guardé como advanced-searchform.php
— pero no lo guardes como searchform.php
porque 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( 'Búsqueda Avanzada', 'textdomain' ); ?></h3>
<!-- PASO ESTO PARA ACTIVAR LA PÁGINA DE RESULTADOS DE BÚSQUEDA AVANZADA DESDE functions.php -->
<input type="hidden" name="search" value="advanced">
<label for="name" class=""><?php _e( 'Nombre: ', 'textdomain' ); ?></label><br>
<input type="text" value="" placeholder="<?php _e( 'Escribe el Nombre del Coche', 'textdomain' ); ?>" name="name" id="name" />
<label for="model" class=""><?php _e( 'Selecciona un Modelo: ', 'textdomain' ); ?></label><br>
<select name="model" id="model">
<option value=""><?php _e( 'Selecciona uno...', 'textdomain' ); ?></option>
<option value="model1"><?php _e( 'Modelo 1', 'textdomain' ); ?></option>
<option value="model2"><?php _e( 'Modelo 1', 'textdomain' ); ?></option>
</select>
<input type="submit" id="searchsubmit" value="Buscar" />
</form>
Luego llama al formulario en tu plantilla de la siguiente manera:
<?php get_template_part( 'advanced', 'searchform' ); ?>
Ahora tu formulario de búsqueda está listo, y puedes usarlo para tomar la entrada del usuario en la URL.
Paso 2
Lo que necesitas ahora es: consultar la base de datos y el tipo de publicación y sus campos personalizados según la consulta de búsqueda. Recuerda que tu consulta de búsqueda ahora es la URL que obtuviste después de enviar el formulario. Ahora indica a WordPress que cargue tu página personalizada de resultados de búsqueda cuando se envíe el formulario. Coloca la siguiente función en tu functions.php
para que active tu 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');
?>
Obtuve este código de algún lugar de WPSE (olvidé la fuente), pero hay controversia al usarlo. Sin embargo, funciona (excusa pobre, por supuesto).
Revisa otra forma que sugirió @G.M.
Paso 3
Crea un nuevo archivo y guárdalo como advanced-search-result.php
(porque usamos este nombre en functions.php
) y ahora estás libre, obviamente. El concepto es:
- Obtener los datos de la URL,
- Usar un simple
WP_Query()
(si tu consulta es compleja, usa una consulta$wpdb
), - Pasar los comandos dentro de la consulta, obtener datos de la base de datos, y
- Mostrar el resultado[s]
Un ejemplo puede ser:
<?php
// Obtener datos de la URL en variables
$_name = $_GET['name'] != '' ? $_GET['name'] : '';
$_model = $_GET['model'] != '' ? $_GET['model'] : '';
// Iniciar la Consulta
$v_args = array(
'post_type' => 'vehicle', // tu CPT
's' => $_name, // busca en todo con la palabra clave de tu 'campo de nombre'
'meta_query' => array(
array(
'key' => 'car_model', // asumimos que tu meta_key es 'car_model'
'value' => $_model,
'compare' => 'LIKE', // encuentra modelos que coincidan con 'model' del campo de selección
),
)
);
$vehicleSearchQuery = new WP_Query( $v_args );
// Descomenta esta línea para depurar la consulta que WordPress acaba de ejecutar
// var_dump($vehicleSearchQuery->request);
// Mostrar los resultados
if( $vehicleSearchQuery->have_posts() ) :
while( $vehicleSearchQuery->have_posts() ) : $vehicleSearchQuery->the_post();
the_title(); // Asumimos que los nombres de tus coches están almacenados como título del CPT
endwhile;
else :
_e( 'Lo sentimos, nada coincide con tus criterios de búsqueda', 'textdomain' );
endif;
wp_reset_postdata();
?>
Entonces, aquí está tu resultado final. Pero aún hay muchos desafíos:
- Valores Alternativos - una búsqueda avanzada puede realizarse con TODOS los campos o con CUALQUIER campo, así que debes asegurarte de que la Consulta tome todos los resultados según la búsqueda y los datos. Puedes usar una consulta SQL personalizada con
$wpdb
para resultados de búsqueda complejos y eso será MySQL puro - WordPress no tiene nada que ver allí. - Saneamiento & Validación - los campos de texto y áreas de texto son tan vulnerables que pueden causar malas prácticas en tu sitio. Por lo tanto, pasar datos crudos sería inseguro, necesitarás Saneamiento y Validación antes de pasarlos a la consulta de la base de datos. (Saneamiento y Validación de Datos con WordPress - TutsPlus)
- Diseño - puedes elegir la plantilla
page.php
(osearch.php
) y hacer esta página basada en eso.
Así que, ya tienes la idea, ahora es tu turno de explorar y descubrir el camino. Recuerda, el camino de cada persona es diferente. Crea el tuyo, para que pueda seguirte. :)

Gracias por tomarte el tiempo, muy amable de tu parte. ¿Sabes cómo puedo hacer para que el menú desplegable de "Marcas" muestre automáticamente cualquier marca que se haya ingresado en una de las publicaciones de vehículos?

¿Sabes cómo puedo hacer para que el menú desplegable de "Marcas" muestre automáticamente cualquier marca que se haya ingresado en una de las publicaciones de vehículos?

usa un WP_Query()
con parámetros de campos personalizados y recorre el resultado para mostrar los <option>
.
