Blog

Búsqueda avanzada en WordPress

Hace poco para un proyecto necesitaba hacer un buscador avanzado, que me mostrara resultados en base a ciertos criterios y como siempre ha sido criticado, el sistema de búsqueda de wordpress es muy limitada.

Existen una serie de plugins para poder mejorar la funcionalidad, desde un Search API creado por Justin Shreve. Hasta plugins como WP Custom Search de Benjamin. Un buen plugin pero es difícil de modificar y en un proyecto anterior hacia conflicto con Jquery.

No es nada nuevo (para mi lo fue en su momento) pues muchas veces queremos buscar en cierta categoría, o en cierta taxonomía, algún custom field, etc.

¿Cómo funciona el formulario de búsqueda?

Cuando hacemos un query, le mandamos los parámetros para que nos muestre los posts de la categoría X, o la taxonomía Y, etc. Con el formulario es igual, por medio de hidden fields (en el más básico de los casos) o selects, checkboxes y campos de texto creamos el query para poder hacer la búsqueda.

¡Ya los ejemplos!

Buscar en una categoría específica

Imaginemos que quiero buscar en mi blog solo en la categoría portafolio, el código sería así:

<form method=”get” id=”searchform” action=”<?php bloginfo(‘home’); ?>/”>
<div>
<input type=”text” value=”<?php echo wp_specialchars($s, 1); ?>” name=”s” id=”s” />
<input type=”hidden” name=”cat” value=”5″ />
<input type=”submit” id=”searchsubmit” value=”Buscar” />
</div>
</form>

Donde con un campo invisible  coloco la categoría que deseo, pero es engorroso buscar el id de la categoría pues muchas veces cuando uno trabaja en local los id’s cambian ya en el WordPress de producción, ¡pero no se asusten! Podemos quitarnos esa piedra del zapato con una función donde es mucho más fácil por nombre de categoría así:

$id_categoria = get_cat_id('Coloco el nombre de la categoría');

Para que al final nos quede algo así:

<form method=”get” id=”searchform” action=”<?php bloginfo(‘home’); ?>/”>
<div><?php $id_categoria = get_cat_id('portafolio'); ?>
<input type=”text” value=”<?php echo wp_specialchars($s, 1); ?>” name=”s” id=”s” />
<input type=”hidden” name=”cat” value=”<?php echo $id_categoria; ?>″ />
<input type=”submit” id=”searchsubmit” value=”Buscar” />
</div>
</form>

Pero que si no quiero que busquen en una sola categoría, sino que pueda elegir en que categoría buscar de todas las que tengo. Solo cambiamos el campo nombrado “cat” (de categoría) por un select con el mismo nombre y usando la función dropdown_categories nos queda así:

<?php wp_dropdown_categories('show_count=0&hierarchical=1&depth=1'); ?>

Podemos cambiar a mostrar la lista de tags, todas las categorías, solo las categorías principales todo depende de la configuración de esta función.

Buscar solo los hijos de una categoría

Siempre seguimos con los select y esta vez utilizamos la función get_categories() digamos que quiero las subcategorías de mi categoría principal llamada Sodas y bajo esta categoría se encuentran los sabores de gaseosas.

<form method=”get” id=”searchform” action=”<?php bloginfo(‘home’); ?>/”>
<div id=”search”>
<input type=”text” value=”Search… ” name=”s” id=”s” />
<?php $id_categoria = get_cat_id('sodas'); ?>
<?php $categorias = get_categories(‘child_of=$id_categoria′);
$catlist = ”;
foreach ($categorias as $cat) {
$lista_cat.= $cat->cat_ID.’,';
}
$lista_cat. $id_categoria;
?>
<input type=”hidden” name=”cat” value=”<?php echo “$lista_cat”?>” />
</div><!–/search –>
</form>

Buscando en una taxonomía

Primero debemos tener en cuenta que es una taxonomía, hay un sin fin de tutoriales y explicaciones; para hacerlo fácil es una clasificación de un algo. Ahora como ejemplo, tengo mi taxonomía llamada área donde están concentradas las carreras de una univesidad para las cuales quiero buscar y también esas carreras solo están disponibles en ciertas partes del mundo, entonces quiero un formulario que me busque el tipo de carrera y la ubicación y que me muestre SOLO los resultados que están para esos lugares y que sean el tipo de carrera que deseo.

Lo primero será crear una función que podré utilizar cuantas veces sea por si necesito diferentes formularios, entonces colocamos esto en functions.php.

function get_terms_dropdown($taxonomies, $args){
$myterms = get_terms($taxonomies, $args);
$output ="<select name='".$taxonomies."'>";
foreach($myterms as $term){
$root_url = get_bloginfo('url');
$term_taxonomy=$term->taxonomy;
$term_slug=$term->slug;
$term_name =$term->name;
$link = $term_slug;
$output .="<option value='".$term_name."'>".$term_name."</option>";
}
$output .="</select>";
return $output;
}

Esta función nos toma todos los terminos de una taxonomía que querramos y podemos reutilizarla para las taxonomías que sean.

Entonces regresando tengo mi taxonomía area y ubicación y quiero buscar por ese criterio.

<form method="get" id="searchform" action="<?php bloginfo('home'); ?>/">
<?php
$taxonomies = 'area';
$args = array('orderby'=>'name','hide_empty'=>true);
$area_select = get_terms_dropdown($taxonomies, $args); ?>
<p><label>Elije el area de la carrera que le interesa</label>
<?php echo $area_select; ?></p>
<?php
$taxonomies = 'ubicacion';
$args = array('orderby'=>'name','hide_empty'=>true);
$ubicacion_select = get_terms_dropdown($taxonomies, $args); ?>
<p><label>Elije el lugar donde deseas estudiar</label>
<?php echo $ubicacion_select; ?></p>
<input name="Buscar" type="submit" value="Buscar" />
</form>

Buscando en los custom fields (actualizado 3, junio, 2013)

Esto es muy importante y sobre todo útil, para una inmobiliaria utilicé uno de los plugins listados allá arriba y hasta ahora me dí cuenta que puedo hacer lo mismo pero con mejor control de lo que quiero.

Vamos a hacer un ejemplo que no tiene nada que ver con la inmobiliaria, digamos que tengo una biblioteca virtual, y los libros pueden buscarse por género, titulo y autor. Colocaré entonces un radio que me marque una de las 3 opciones (por supuesto que podemos hacer eso mucho más fácil con taxonomías). El formulario me quedaría así:

<form method="get" id="searchform" action="<?php bloginfo('home'); ?>/">
<input type="text" value="<?php echo wp_specialchars($s, 1); ?>" name="s" id="s" />
<label for="titulo">Buscar por título<input name="key" type="radio" value="titulo" /></label>
<label for="autor">Buscar por autor<input name="key" type="radio" value="autor" /></label>
<label for="genero">Buscar por género: <input name="key" type="radio" value="genero" /></label>
<input type="submit" id="searchsubmit" value="Buscar libro" />
</form>

Básicamente lo que se hace es darle el nombre “key” que hace referencia que es un custom field y le damos el nombre del custom, entonces buscaremos en valor en el campo “s” en el custom field que elijamos.

Actualización 3 de junio 2013

Dado a que los meta_key no son públicos para el query (GET) debemos de hacerlo de otra manera, siguiendo el ejemplo anteior, tenemos ya nuestro query_var “key” que posee una de las 3 opciones titulo, autor, genero.

Vamos a nuestro search.php y vamos a ver algo parecido a esto:

query_posts();

Cambiaremos un poco eso:

$query_string['meta_key'] = (isset($_GET['key'])) ? $_GET['key'] : '';
query_posts($query_string);

Y listo ya busca por meta_keys el meta_value enviado por el radio button. Para conocer que tanto se puede hacer, pueden ver la sección de WP_Query.

Opciones, ¡infinitas!

Básicamente se puede hacer una búsqueda en todo lo que se necesite dependiendo de los condicionales que uno desee aquí está un lista de los que he probado esta el momento.

name=”cat” value=”ID de la categoría” – busca en categorías, con los ID’s de las mismas. Separado en comas (,) para buscar en más de una categoría y le agregamos un signo menos (-) para excluir categorías

name=”key” value=”nombre del custom field” – busca en los custom fields, se coloca el nombre del custom.

name=”tag” value=”el nombre del tag” – busca en los tags y si tiene valor busca en el contenido y que tenga el tag incluido en el post

name=”nombre de la taxonomía” value=”el término de la taxonomía” – al tener varias taxonomías, hace el condicional AND para buscar en entradas que cumplan con las taxonomías, se pueden hacer OR agregando terminos separados por comas (,) en el mismo value de la taxonomía (ejemplo: name=”taxo_talla” value=”small, medium”).

¡Espero que les ayude un poco en su próximo proyecto!