El formulario de búsqueda estándar de WordPress incluye un sólo input, de nombre s, en el que se específica el texto que se quiere buscar. En este tutorial vamos a ver como añadir más parámetros que nos permitan filtrar los resultados de búsqueda con criterios más específicos. Por ejemplo, limitar los resultados de búsqueda a una categoría o a un tipo de post.

Generando un formulario de búsqueda personalizado

El formulario de búsqueda estándar de WordPress lo podemos generar con esta función:

<?php get_search_form(); ?>

El resultado en HTML es:

<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
	<label>
		<span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ) ?></span>
		<input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
	</label>
	<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>

El formulario puede ser personalizado de varias formas, una de las más comunes es creando el archivo searchform.php en la carpeta del tema que tengamos activo. En este archivo podemos poner nuestro propio formulario de búsqueda con todas las demás opciones que queramos y será el utilizado por la función get_search_form(). Por ejemplo:

<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
	<label>
		<span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ) ?></span>
		<input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
	</label>
        <select name="category_name">
            <option value="">Todas las categorías</option>
            <option value="politica">Política</option>
            <option value="eonomia">Economía</option>
        </select>
	<input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>

Ahora que ya sabemos como personalizar el formulario de búsqueda estamos listos para el siguiente paso.

Opciones de búsqueda con query string

Cómo el formulario utiliza method="get", los inputs adicionales que pongamos se enviarán como query strings (pares variable=valor). Y aquí viene lo bueno: podemos utilizar directamente cualquier variable admitida por WP Query en formato query string. Por ejemplo, podemos utilizar category_name y post_type:

<form role="search" method="get" class="search-form" action="<?php echo home_url( '/' ); ?>">
    <label>
        <span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ) ?></span>
        <input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
    </label>
    <select name="category_name">
        <option value="">Todas las categorías</option>
        <option value="politica">Política</option>
        <option value="eonomia">Economía</option>
    </select>
    <select name="post_type">
        <option value="any">Todos los tipos</option>
        <option value="post">Post estándar</option>
        <option value="noticia">Noticias</option>
    </select>
    <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>

Supongamos que en el formulario anterior introducimos «euro» como término de búsqueda y seleccionamos «Economía» como categoría y «Noticias» como tipo de post. Al enviar el formulario se generará esta URL: http://misitio.com/?s=euro&category_name=economia&post_type=noticia. Cómo las variables del query string tienen nombres admitidos por WP Query, WordPress los utilizará para filtrar los resultados de búsqueda sin que tengamos que hacer nada más. Así de sencillo.

Una lista de variables estándar que podemos utilizar (no exhaustiva):

  • category_name: nombre (slug) de una categoría (taxonomía «Categories» del core). Admite varias separadas por coma; por ejemplo, category_name=economia,politica.
  • cat: ID de una categoría (taxonomía «Categories» del core). Admite varias separadas por coma.
  • p: ID de un post de cualquier tipo.
  • name: slug de un post de cualquier tipo.
  • pagename y page_id
  • author y author_name
  • tag y tag_id para filtrar por etiquetas. (taxonomía post_tag del core).
  • post_type: slug del tipo de post. post_type=any para mostrar posts de cualquier tipo.
  • variables de fecha: year, month, day.

Para una lista más completa y ver todas las opciones de cada variable mira la documentación de WP Query.

Ejemplo

En el siguiente ejemplo obtendremos todas las categorías como opciones de un elemento select utilizando la función wp_dropdown_categories(). La categoría seleccionada será utilizada de forma automática por WordPress para filtrar los resultados de búsqueda:

<form role="search" method="get" class="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    <label>
        <span class="screen-reader-text"><?php echo _x( 'Search for:', 'label' ) ?></span>
        <input type="search" class="search-field" placeholder="<?php echo esc_attr_x( 'Search …', 'placeholder' ) ?>" value="<?php echo get_search_query() ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label' ) ?>" />
    </label>
    <label for="cat"><?php echo _x( 'Choose a category:', 'label' ) ?></label>
    <?php wp_dropdown_categories(); ?>
    <input type="submit" class="search-submit" value="<?php echo esc_attr_x( 'Search', 'submit button' ) ?>" />
</form>

Búsqueda avanzada con pre_get_posts action

El action hook pre_get_posts nos permite manipular el query principal de WordPress antes de que se ejecute. En otras palabras, podemos decirle a WordPress los criterios exactos que queremos que utilice para buscar los posts en la base de datos. En el callback se recibe un objeto WP Query que podemos manipular a nuestro antojo.

Ejemplo

Excluir de los resultados de búsqueda aquellos posts que estén en la categoría 1 o 2:

add_action( 'pre_get_posts', 'include_any_post_type_in_search' );
function include_any_post_type_in_search( $query ) {
    //Comprobamos que NO estamos en el área de administración,
    //que el query es para una búsqueda
    //y que es el query principal
    if ( ! is_admin() && $query->is_search && $query->is_main_query() ) {
        //Excluir posts que estén en alguna de estas categorías
        $query->set( 'category__not_in', array( 1, 2 ) );
    }
}

Cómo ves, añadir funcionalidad extra a la búsqueda en WordPress es muy sencillo y con el action pre_get_posts las posibilidades son ilimitadas.