Por defecto, la búsqueda en WordPress se realiza a través del contenido y los títulos de las publicaciones. Si tienes un sitio web avanzado donde los datos se almacenan en campos personalizados, es posible que desees incluir esos valores en los resultados de búsqueda. En esta guía, te proporcionaré el código necesario para actualizar WordPress y permitir la búsqueda en campos personalizados, todo esto sin necesidad de utilizar un plugin de terceros.
Si no eres desarrollador o te sientes inseguro al agregar código personalizado a tu sitio web, te recomendaría utilizar un plugin de terceros como SearchWP o Relevanssi. Ambos plugins son completamente gratuitos, aunque ofrecen opciones de actualización premium.
Nota de precaución: El código que se proporciona en este tutorial hará que WordPress utilice TODOS los valores de los campos personalizados en el cálculo de búsqueda. Dependiendo de tu sitio, esto podría generar preocupaciones de seguridad o ralentizar tus consultas de búsqueda.
¿Por qué buscar en campos personalizados?
Hace un tiempo escribimos un artículo sobre por qué y cómo mejorar la búsqueda interna de WordPress. En ese artículo se abordan las razones para mejorar la búsqueda de tu sitio en WordPress y cuáles son los mejores plugins para ello. Por lo tanto, en lugar de reiterar todo aquí, te invito a que revises ese post.
Sin embargo, un ejemplo podría ser un sitio web que tenga un tipo de publicación para los miembros del personal de una organización. Para estos miembros, es probable que tengas campos personalizados para almacenar datos como su título profesional, habilidades, educación, etc. Por lo tanto, querrás incluir estos campos en el cálculo de búsqueda de WordPress para facilitar la localización de miembros.
Aun así, antes de modificar cómo funciona la búsqueda en WordPress, tómate un momento para reflexionar si realmente lo necesitas. Existen situaciones donde modificar los resultados de búsqueda no proporcionará la mejor experiencia de usuario. Podría ser más efectivo crear un filtro AJAX para que los usuarios puedan seleccionar valores de varios campos y así limitar las publicaciones mostradas.
Cómo buscar por campos personalizados sin un plugin
Para permitir que los valores de los campos personalizados se incluyan en los resultados de búsqueda de WordPress, necesitaremos enganchar tres filtros diferentes (uno opcional). Filtraremos las cláusulas JOIN, WHERE y DISTINCT de la consulta de búsqueda. Te guiaré a través de cada filtro y explicaré su funcionamiento.
Paso 1: Filtrar la cláusula JOIN
Comenzaremos modificando la cláusula JOIN a través del filtro posts_join
.
/**
* Agrega la tabla postmeta a la consulta de búsqueda.
*
* @link https://www.wpexplorer.com/how-to-include-custom-field-values-in-wordpress-search/
*/
function wpexplorer_search_posts_join( $join, $query ) {
if ( $query->is_search() ) {
global $wpdb;
$join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
}
return $join;
}
add_filter( 'posts_join', 'wpexplorer_search_posts_join', 10, 2 );
Por defecto, WordPress está configurado para buscar solo en la tabla «posts» y dado que los campos personalizados se almacenan en la tabla «postmeta», necesitaremos incluirla en la consulta. Eso es lo que hace el fragmento anterior.
Paso 2: Filtrar la cláusula WHERE
A continuación, filtraremos la cláusula WHERE enganchándonos al hook posts_where
.
/**
* Agrega valores meta a la consulta de búsqueda.
*
* @link https://www.wpexplorer.com/how-to-include-custom-field-values-in-wordpress-search/
*/
function wpexplorer_search_posts_where( $where, $query ) {
if ( $query->is_search() ) {
global $wpdb;
$where = preg_replace(
"/\(\s*{$wpdb->posts}.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"({$wpdb->posts}.post_title LIKE $1) OR ({$wpdb->postmeta}.meta_value LIKE $1)",
$where
);
}
return $where;
}
add_filter( 'posts_where', 'wpexplorer_search_posts_where', 10, 2 );
El código anterior indica a la consulta de búsqueda de WordPress que busque en la columna meta_value. Una vez más, esto incluirá todos los campos personalizados. Si solo deseas que WordPress busque en campos específicos, el código será mucho más complejo.
Paso 3: Filtrar la cláusula DISTINCT (opcional)
Por último, filtraremos el hook posts_distinct
.
/**
* Evita duplicados en los resultados de búsqueda.
*
* @link https://www.wpexplorer.com/how-to-include-custom-field-values-in-wordpress-search/
*/
function wpexplorer_search_posts_distinct( $where, $query ) {
if ( $query->is_search() ) {
return "DISTINCT";
}
return $where;
}
add_filter( 'posts_distinct', 'wpexplorer_search_posts_distinct', 10, 2 );
Esta última línea de código previene que se muestren publicaciones duplicadas en los resultados de búsqueda si tienes campos personalizados con los mismos valores en diferentes campos. Esto no suele ser un problema, pero vale la pena mencionarlo. No obstante, añadir el código no causa daño (al menos, no lo creo).
Clase PHP & Plugin
Para facilitar las cosas, he compilado los 3 fragmentos anteriores en una única clase que puedes añadir a tu sitio. Utilizar una clase mantendrá el código separado y bien organizado. Puedes agregar el código a tu archivo functions.php de tu tema hijo o a un plugin de fragmentos de código.
Recomiendo agregar la clase PHP en su propio archivo en tu tema hijo y cargarla usando require. Esto mantendrá tu código ordenado, evitando un archivo functions.php demasiado extenso.
/**
* Permitir la búsqueda por campos personalizados.
*
* @link https://www.wpexplorer.com/how-to-include-custom-field-values-in-wordpress-search/
*/
final class Search_By_Custom_Fields {
/**
* Constructor de clase.
*/
public function __construct() {
add_filter( 'posts_join', [ $this, 'filter_posts_join' ], 10, 2 );
add_filter( 'posts_where', [ $this, 'filter_posts_where' ], 10, 2 );
add_filter( 'posts_distinct', [ $this, 'filter_posts_distinct' ], 10, 2 );
}
/**
* Agrega la tabla postmeta a la consulta de búsqueda.
*/
public function filter_posts_join( $join, $query ) {
if ( $query->is_search() ) {
global $wpdb;
$join .= " LEFT JOIN {$wpdb->postmeta} ON {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id";
}
return $join;
}
/**
* Agrega valores meta a la consulta de búsqueda.
*/
public function filter_posts_where( $where, $query ) {
if ( $query->is_search() ) {
global $wpdb;
$where = preg_replace(
"/\(\s*{$wpdb->posts}.post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
"({$wpdb->posts}.post_title LIKE $1) OR ({$wpdb->postmeta}.meta_value LIKE $1)",
$where
);
}
return $where;
}
/**
* Evita duplicados en los resultados de búsqueda.
*/
public function filter_posts_distinct( $where, $query ) {
if ( $query->is_search() ) {
return "DISTINCT";
}
return $where;
}
}
new Search_By_Custom_Fields();
Descargar el Plugin
También he añadido el código anterior a Github para que puedas descargarlo como un plugin. Este plugin no se subirá al repositorio de WordPress, por lo que no recibirás actualizaciones. Al descargarlo, puedes modificar el nombre de la carpeta y los detalles del plugin según tus necesidades.
Prefiero crear mini plugins para códigos como este. Al tener el código dentro de un plugin, resulta más fácil solucionar problemas en el sitio, ya que puedes desactivar rápidamente fragmentos problemáticos. De hecho, tengo más de 50 mini plugins en wpexplorer.com que realizan diversas tareas.
Conclusión
Como puedes ver, incluir valores de campos personalizados en la búsqueda interna de WordPress es sencillo. Sin duda hay situaciones en las que puede resultar útil. Si tienes alguna consulta o problema relacionado con el código, no dudes en hacérmelo saber.
Además, me gustaría conocer ejemplos reales de sitios web que utilicen campos personalizados en sus resultados de búsqueda para mejorar la experiencia del usuario. ¡Compártelos en los comentarios!
Lectura adicional
Mientras estás aquí, podrías querer leer algunos tutoriales relacionados: