Búsqueda Multisite (Network, MU, MultiUser)
Tabla de contenidos
SearchWP es capaz de realizar búsquedas Multisite/Network entre sitios. Hay varias cosas que mencionar/considerar con respecto a la implementación.
Nota: ¡Hay limitaciones importantes a tener en cuenta!
Resumen
Las búsquedas entre sitios son posibles en SearchWP. Se puede utilizar cualquier motor de cualquier sitio para una búsqueda entre sitios.
Nota: Los motores de SearchWP controlan lo que se indexa en cada sub-sitio. Si el motor que estás utilizando para realizar la búsqueda tiene Fuentes/Atributos/Reglas diferentes a los motores de los sub-sitios que estás buscando, los resultados pueden no ser precisos.
Por ejemplo: si se han añadido Entradas al motor que estás utilizando para la búsqueda, pero un sub-sitio no tiene Entradas habilitadas en su motor, ese sub-sitio no devolverá Entradas.
Para una búsqueda exhaustiva entre sitios, asegúrate de que todos los sitios compartan una configuración similar y un motor aplicable.
Detalles de implementación
En un entorno Multisite, SearchWP construye un índice de búsqueda completo para la totalidad de la red. Por defecto, SearchWP limitará los resultados a las Entradas del sitio actual.
Puedes utilizar \SearchWP\Query para ejecutar búsquedas en múltiples sitios dentro de la red personalizando el parámetro site para que contenga:
- Matriz de IDs de sitio (o una cadena de IDs de sitio separada por comas)
'all'para buscar en todos los sitios de la red
Importante: el concepto principal a entender es que los motores de SearchWP determinan qué contenido se indexa para todos los sitios dentro de una red.
Esto es significativo porque \SearchWP\Query utiliza un motor del sitio actual para realizar la búsqueda. Digamos que el motor predeterminado del sitio actual (SITIO A) tiene las siguientes Fuentes y nada más:
- Entradas
- Páginas
Dentro de esta red de ejemplo, hay un segundo sitio (SITIO B) que tiene un motor predeterminado con las siguientes Fuentes y nada más:
- Entradas
Si estás realizando una \SearchWP\Query en el SITIO A utilizando su motor predeterminado, las Páginas del SITIO B no se devolverán porque las Páginas no se añadieron al motor predeterminado del SITIO B.
Esto puede parecer contraintuitivo porque las Páginas sí se añaden al motor predeterminado del SITIO A, pero los motores del SITIO B definen y controlan lo que se indexa para ese sitio.
Configuración recomendada del motor
Dado lo anterior, puedes utilizar un motor suplementario en cada sitio de la red que comparta una configuración común.
Alternativamente, puede asegurarse de que su red esté configurada de tal manera que el Motor utilizado para una \SearchWP\Query sea el denominador común más pequeño para todos los sitios dentro de la red.
Manejo de resultados de búsqueda Multisite
\SearchWP\Query le permite especificar cómo se devuelven los resultados utilizando el parámetro fields.
Por defecto, los resultados se devuelven como una matriz de objetos, cada uno con las siguientes propiedades: 'id', 'source', 'site', 'relevance'
Este formato es el más útil para los resultados de búsqueda de Multisitio porque le brinda la capacidad de switch_to_blog() cuando sea necesario para recuperar detalles precisos para cada resultado.
Si, sin embargo, elige usar otro formato compatible, es posible que no incluya información crítica del ID del sitio, así que tenga esto en cuenta al estructurar sus búsquedas de Multisitio.
Nota: Esto se aplica específicamente cuando se establece fields en 'all', lo que devolverá cada resultado en su formato nativo (por ejemplo, como \WP_Post). Cualquier suposición hecha en la salida de sus resultados (por ejemplo, el uso de get_permalink()) se basa en el sitio actual, ¡no necesariamente en el sitio del que se devolvió el resultado!
Dado esto, siempre se recomienda usar el valor predeterminado para fields y switch_to_blog() manualmente (y posteriormente restore_current_blog()) cuando sea necesario.
Ejemplos
Hay dos formas principales de implementar una búsqueda Multisitio entre sitios:
- Anular la búsqueda nativa/predeterminada en un sitio dentro de la red
- Configurar una búsqueda Multisitio dedicada entre sitios
La primera es probablemente más común, pero es ligeramente más compleja que configurar una búsqueda más directa y dedicada. Ambas opciones se cubren aquí. ?
Anulación de la predeterminada
Si desea anular el comportamiento de búsqueda predeterminado de un sitio Multisitio para buscar en toda la red, podemos anular los argumentos nativos del sitio para hacer precisamente eso.
Ejemplo: Hay una universidad que tiene un sitio 'principal', con muchos sub-sitios Multisitio para varias escuelas/departamentos/etc. y queremos anular la búsqueda en el sitio principal para buscar en toda la instalación Multisitio. Todos los Motores Predeterminados son los mismos en toda la red Multisitio.
Hay dos pasos a seguir:
- Filtrar los argumentos enviados a SearchWP para buscar en toda la red
- Actualizar la plantilla de resultados de búsqueda para tener en cuenta los cambios de sitio
Filtrar argumentos para la búsqueda del sitio principal
Dado que estamos personalizando la página de resultados de búsqueda nativa, usaremos el hook searchwp\native\args para indicarle a SearchWP que queremos buscar en toda la red Multisitio:
All hooks should be added to your custom SearchWP Customizations Plugin.
| <?php | |
| // @link https://searchwp.com/documentation/multisite/ | |
| // Tell SearchWP to search the entire Multisite network when searching on the main site. | |
| add_filter( 'searchwp\query\args', function( $args, $query ) { | |
| // If this is not site 1, bail out. | |
| if ( 1 !== get_current_blog_id() ) { | |
| return $args; | |
| } | |
| // Search sites with ID 1, 2, 3. | |
| $args['site'] = [1,2,3]; | |
| // Retain site info in results. | |
| $args['fields'] = 'default'; | |
| return $args; | |
| }, 10, 2 ); |
Tenga en cuenta que también le estamos diciendo a SearchWP que devuelva resultados default (en lugar de WP_Post), lo que nos lleva al paso 2:
Actualizar plantilla de resultados de búsqueda
En el paso 1 le dijimos a SearchWP que buscara en toda la red Multisite y que *no* formateara los resultados como WP_Posts, sino que mantuviera los resultados en su forma original, que contiene la información del sitio que necesitamos para generar resultados adecuados en tiempo de ejecución.
Necesitamos actualizar The Loop de nuestra salida en la plantilla search.php de Resultados de Búsqueda de nuestro tema para tener en cuenta los resultados formateados por SearchWP:
| <?php | |
| // @link https://searchwp.com/documentation/multisite/ | |
| global $post; | |
| $current_blog_id = get_current_blog_id(); | |
| get_header(); | |
| if ( have_posts() ) { | |
| while ( have_posts() ) { | |
| the_post(); | |
| // Search Results may be formatted as SearchWP results | |
| // because we're searching cross-site on the main site. | |
| if ( 1 === $current_blog_id ) { | |
| if ( $current_blog_id !== $post->site ) { | |
| switch_to_blog( $post->site ); | |
| $post = get_post( $post->id ); | |
| get_template_part( 'search-result' ); | |
| restore_current_blog(); | |
| } else { | |
| $post = get_post( $post->id ); | |
| get_template_part( 'search-result' ); | |
| } | |
| } else { | |
| get_template_part( 'search-result' ); | |
| } | |
| } | |
| } else { | |
| get_template_part( 'template-parts/content/content-none' ); | |
| } | |
| get_footer(); |
Tenga en cuenta que la plantilla de resultados todavía se basa en The Loop, pero estamos personalizando el comportamiento si estamos mostrando resultados en el sitio 1 (el sitio principal) para tener en cuenta posibles cambios en el sitio.
Tenga en cuenta también que se utiliza una parte de plantilla para mostrar los resultados, pero en el caso de que un resultado se devuelva de un sitio *diferente*, la plantilla se incluye *antes* de que llamemos a restore_current_blog().
Esto es necesario para asegurar que las llamadas a funciones como get_permalink() se ejecuten en el contexto adecuado *antes* de volver al sitio principal para mostrar el siguiente resultado.
Uso de un motor suplementario
Al implementar una búsqueda multisitio entre sitios diseñada específicamente, puede seguir las mismas instrucciones para crear un Motor Suplementario.
Con su Motor Suplementario configurado, primero podemos personalizar la ejecución de la búsqueda para buscar en toda la red Multisite:
| <?php | |
| // ... this overrides the \SearchWP\Query instantiation found | |
| // @link https://searchwp.com/documentation/search/supplemental-engine/ | |
| // e.g. $search_page is defined in the full snippet, this solely | |
| // replaces the query to search across sites and return 'default' results. | |
| $searchwp_query = new \SearchWP\Query( $search_query, [ | |
| 'engine' => 'supplemental', // The Engine name. | |
| 'fields' => 'default', // Retain site ID info with results. | |
| 'site' => 'all', // Search all sites. | |
| 'page' => $search_page, | |
| ] ); |
Las dos ediciones realizadas son:
- Definir
fieldspara devolver los camposdefault(que contienen información del ID del sitio) - Especificar que debemos buscar en
allsitios
Con ese cambio realizado en la implementación del Motor Suplementario, SearchWP buscará en toda la red Multisite y devolverá resultados default, por lo que necesitaremos actualizar la salida de los resultados para verificar cada resultado en busca de un sitio diferente:
Nota: Por brevedad, este fragmento actualiza *solo la salida de resultados* de la implementación completa del Motor Suplementario.
| <?php | |
| // ... this snippet overrides the results output found | |
| // @link https://searchwp.com/documentation/search/supplemental-engine/ | |
| // so as to account for results that are from a different Multisite site. | |
| // This is not a full and complete example, it shows only the customization | |
| // to the results output to account for site changes. | |
| // Track the current blog ID. | |
| $current_blog_id = get_current_blog_id(); | |
| ?> | |
| <?php if ( ! empty( $search_query ) && ! empty( $search_results ) ) : ?> | |
| <?php foreach ( $search_results as $search_result ) : ?> | |
| <article class="page hentry search-result"> | |
| <?php | |
| // Track whether we switched sites for this result. | |
| $switched_site = false; | |
| // Do we need to switch to the proper site for this result? | |
| if ( $current_blog_id !== $search_result->site ) { | |
| switch_to_blog( $search_result->site ); | |
| $switched_site = true; | |
| } | |
| // Output the result based on SearchWP Source. | |
| switch( $search_result->source ) { | |
| // Posts and Pages. | |
| case 'post' . SEARCHWP_SEPARATOR . 'post': | |
| case 'post' . SEARCHWP_SEPARATOR . 'page': | |
| $post = get_post( $search_result->id ); | |
| ?> | |
| <header class="entry-header"><h2 class="entry-title"> | |
| <a href="<?php echo get_permalink(); ?>"><?php the_title(); ?></a> | |
| </h2></header> | |
| <div class="entry-summary"><?php the_excerpt(); ?></div> | |
| <?php | |
| wp_reset_postdata(); | |
| break; | |
| // Users. | |
| case 'user': | |
| ?> | |
| <header class="entry-header"><h2 class="entry-title"> | |
| <a href="<?php echo get_author_posts_url( $search_result->id ); ?>"> | |
| <?php echo esc_html( get_the_author_meta( 'display_name', $search_result->id ) ); ?> | |
| </a> | |
| </h2></header> | |
| <div class="entry-summary"> | |
| <?php echo wp_kses_post( get_the_author_meta( 'description', $search_result->id ) ); ?> | |
| </div> | |
| <?php | |
| break; | |
| } | |
| ?> | |
| </article> | |
| <?php | |
| // If we switched sites, switch back! | |
| if ( $switched_site ) { | |
| restore_current_blog(); | |
| } | |
| ?> | |
| <?php endforeach; ?> | |
| <?php endif; ?> |
En este segmento de fragmento podemos ver que ahora estamos prestando atención tanto al formato de resultados devuelto por SearchWP (default en lugar de los objetos de resultados nativos) que contienen la información que necesitamos sobre el sitio de origen de cada resultado.
A medida que iteramos sobre los resultados, llamamos a switch_to_blog() cuando es necesario, y aún podemos mostrar resultados de cualquier Fuente de SearchWP utilizando el source, site e id de cada resultado.
Tenga en cuenta que debe (y en la mayoría de los casos *necesitará*) mostrar todos los datos relevantes para cada resultado *antes* de llamar a restore_current_blog() porque muchas funciones (por ejemplo, get_permalink()) necesitan ejecutarse en el contexto del sitio correcto, por lo que llamar a restore_current_blog() (cuando sea aplicable) lo más tarde posible es siempre la mejor opción.

