Ofrecer sugerencias en tu WordPress usando opensearch

Creo que para ciertos blogs es muy útil ofrecer la opción de añadir OpenSearch para que la gente puede realizar búsquedas en nuestro blog. Algo también bastante útil es que nos ofrezca sugerencias de búsquedas (tal y como hace Google). Para ello tan sólo hay que añadir una opción al XML de OpenSearch y modificar nuestro functions.php.

En el fichero XML deberemos añadir la siguiente etiqueta:

Y añadir xmlns:suggestions="http://www.opensearch.org/specifications/opensearch/extensions/suggestions/1.1" a la etiqueta inicial OpenSearchDescription

Yo en este caso he preferido usar una URL amigable, sobre todo para practicar con el wp_rewrite, pero se podría hacer perfectamente con una variable con parámetros.

Una vez cambiado el opensearch.xml deberemos modificar el functions.php, para lo cual tendremos que coger el término que se quiere sugerir y buscar entre las categorías y tags y entre los títulos de los posts para así mostrar una unión de ambos. Las categorías se ordenarán por el número de veces que aparece y los posts por fecha descendente.

add_filter('init','suggestion_init');
add_filter('query_vars','suggestion_insertMyRewriteQueryVars');
add_filter('rewrite_rules_array','suggestion_rewrite');

// Acciones iniciales
function suggestion_init(){
  // Reescribe las reglas
  global $wp_rewrite;
  $wp_rewrite->rewrite_rules();

  // Obtiene el termino a buscar
  $req = explode('/', substr($_SERVER['REQUEST_URI'], 1), 2);
  if ($req[0] == 'suggestion') {
    $result = wp_cache_get( 'suggestion_'.$req[1] );
    if ( false == $result ) {
      global $wpdb;
      $list = array();
      // Recupera las 4 categorias/tags que coincidan
      $res = $wpdb->get_results("select name from $wpdb->terms t, $wpdb->term_taxonomy tx where name like '%".$req[1]."%' and t.term_id = tx.term_id group by name order by count desc limit 4");
      foreach ($res as $item) $list[] = $item->name; 
      // Recupera las 4 anotaciones que coincidan   
      $res = $wpdb->get_results("select post_title from $wpdb->posts where post_title like '%".$req[1]."%' order by ID desc limit 4");
      foreach ($res as $item) $list[] = $item->post_title;
      // Devuelve en formato JSON     
    	$result = json_encode(array($req[1], $list));
    	wp_cache_set( 'suggestion_'.$req[1], $result );
    } 

    echo $result;
    exit();
  }
}

// Permite que WP acepte un nueva parametro en la query de la URL
function suggestion_insertMyRewriteQueryVars($vars) {
    array_push($vars, 'suggestion');
    return $vars;
}

// Reescribe la regla
function suggestion_rewrite($rules)
{
	$newrules = array();
	$newrules['suggestion/([^/]+)/(.*)$'] = 'index.php?suggestion=$matches[1]';
	return $newrules + $rules;
}

En el código he añadido caché, porque es altamente recomendable, puediendo usar el plugin WP File Cache. También debo decir que me encontré con el problema del timeout que tiene Firefox para esperar la respuesta para la sugerencia, muy pequeño para mi servidor, por lo que si quieres modificarlo, busca el fichero nsSearchSuggestions.js y modifica el valor de _suggestionTimeout.

| |

Laboratorio: reconocimiento de un motor de búsqueda para navegadores

Una de las características más útiles que poseen actualmente los navegadores es la posibilidad de personalizar y añadir motores de búsqueda. Firefox lo dispone desde hace tiempo e Internet Explorer lo ha añadido en su última versión. Para poder tener un poco de orden en la creación de estos motores existe OpenSearch, que tal como dice la Wikipedia es:

es un conjunto de tecnologías que permiten publicar los resultados de una búsqueda en un formato adecuado para la sindicación y agregación. Es una forma para que las páginas web y los motores de búsqueda publiquen sus resultados de forma accesible

El proceso es sencillo, añades un XML en tu web y un acceso desde tus páginas para que el navegador lo reconozca y te avise de que existe para instalarlo directamente.

El XML sería el siguiente:

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Sentido Web</ShortName>
<LongName>Sentido Web - Actualidad, productividad y desarrollo web...</LongName>
<Description>Encuentra todo lo que necesitas en tu día a día del desarrollo web.</Description>
<Tags>sentidoweb web internet blogs bitácoras weblogs web2.0 estándares css xhtml web-semántica php javascript</Tags>
<Contact>info@blogsmedia.com</Contact>
<Url type="text/html"     template="http://sentidoweb.com/bm/mt-search.cgi?IncludeBlogs=1&amp;search={searchTerms}&amp;submit.x=0&amp;submit.y=0&amp;submit=Buscar"/>
<Image height="16" width="16" type="image/vnd.microsoft.icon">http://sentidoweb.com/i/favicon.ico</Image>
<Query role="example" searchTerms="php" />
<Developer>Luis Sacristán Pascual</Developer>
<Attribution>BlogsMedia 2007, Creative Commons (Reconocimiento-NoComercial-SinObraDerivada 2.5)</Attribution>
<SyndicationRight>open</SyndicationRight>
<AdultContent>false</AdultContent>
<Language>es-es</Language>
<OutputEncoding>UTF-8</OutputEncoding>
<InputEncoding>UTF-8</InputEncoding>
</OpenSearchDescription>

Y la línea que hay que añadir a nuestras páginas en el header es la siguiente:

<link rel="search" type="application/opensearchdescription+xml"
href="http://dominio/path/opensearch.xml" title="Nuestro buscador" />

El XML de arriba es el que usamos para Sentido Web y aunque su lectura es clara, explicaremos cada una de las etiquetas del XML:

  • OpenSearchDescription: es la cabecera del XML de OpenSearch.
  • ShortName: contiene el nombre corto que identifica al motor de búsqueda. Debe tener como máximo 16 caracteres.
  • LongName: contiene el nombre largo que identifica al motor de búsqueda. Debe tener como máximo 48 caracteres.
  • Description: descripción del motor de búsqueda. Debe tener un máximo de 1024 caracteres.
  • Tags: conjunto de palabras separadas por espacios que describen el tipo de contenido que nos encontraremos en las búsquedas. Debe tener un máximo de 256 caracteres.
  • Contact: e-mail de contacto.
  • Url: indica el interfaz que el cliente (navegador) podrá utilizar para realizar la búsqueda. Dispone de varios parámetros que nos permiten personalizar la búsqueda:
    • type: tipo MIME del resultado de la búsqueda. Puede ser por ejemplo application/rss+xml para RSS o application/xhtml+xml para XHTML.
    • template: la plantilla de la URL para indicar al cliente cómo realizar la búsqueda, usando esta sintaxis.
    • indexOffset: contiene el índice del primer resultado de búsqueda.
    • pageOffset: contiene el número de la primera página de resultados.
  • Image: URL de la imagen que se asocia al buscador.
  • Query: define una búsqueda pueden realizar los clientes, más información aquí.
  • Developer: creador del xml.
  • AttributionEntidades a las que se les asocia el motor de búsqueda.
  • SyndicationRight: el grado de resultados que provee el buscador que se pueden buscar, mostrar y redistribuir.
  • AdultContent: indica si hay contenido para adultos.
  • Language: idioma del resultado de la búsqueda.
  • OutputEncoding: codificación de los datos de salida.
  • InputEncoding: codificación de los datos de entrada.

Existen otras etiquetas y se le pueden añadir otras si se indica un xmlns en la etiqueta OpenSearchDescription.