# Plan — Buscador avanzado NATIVO (feadulta #8, sin Typesense) > **Para el agente ejecutor (Sonnet).** Replica el «Buscador avanzado» del Joomla viejo > con WordPress nativo + MySQL FULLTEXT. Corre en el hosting actual (sin Docker/servicios). > Typesense queda como mejora futura opcional (`docs/plan-buscador-typesense.md`). ## ⛔ Restricciones DURAS - **Trabaja SOLO en LOCAL** (contenedor Docker `wordpress-web`, navegable en `http://localhost:8081/`; equivalente Tailscale `https://farmer.taild3aaf6.ts.net/fea/`). - **NO toques producción.** No abras SSH a `feadulta@134.0.10.170`. No despliegues nada. - **NO commitees.** Deja el working tree listo; Rafa verifica antes de subir. - wp-cli: usa `docker exec wordpress-web wp eval '' --allow-root` y `wp eval-file`. **`wp db query` NO funciona** en este contenedor (sin binario mysql) → para SQL usa `global $wpdb; $wpdb->query(...)` dentro de `wp eval`. - No metas bloques Gutenberg (``) en `post_content` vía CLI (se guardan literales). - Sigue el estilo de los mu-plugins existentes (`wordpress/wp-content/mu-plugins/fea-*.php`). ## Contexto ya hecho (fase 1, MVP nativo, en prod y local) - `mu-plugins/fea-search.php`: barra de búsqueda visible en móvil; action a la raíz del idioma (Polylang). En desktop se usa el buscador del menú. - Template FSE `search` (creado con `scripts/set_search_template.php`) que muestra los resultados en **rejilla de tarjetas** reutilizando las clases `fea-archive-grid` / `fea-archive-card` (las del `archive`, #63). En local es el wp_template post 53826. - La búsqueda nativa `/?s=` funciona. ## Qué tenía el «Buscador avanzado» K2 (a replicar) Cinco modos: **palabra**, **autor**, **tema (categoría)**, **cita bíblica**, **fecha**. ## Implementación ### 1. Motor: MySQL FULLTEXT - Verifica engine/versión: `SELECT VERSION()`, engine de `wp_posts` (esperado InnoDB, MySQL ≥5.6). - Añade índice (idempotente; comprueba antes con `SHOW INDEX ... WHERE Index_type='FULLTEXT'`): `ALTER TABLE wp_posts ADD FULLTEXT fea_ft (post_title, post_content);` - mu-plugin **`fea-search-fulltext.php`**: en `is_search() && is_main_query() && !is_admin()` y con términos, sustituye el `LIKE` por `MATCH(wp_posts.post_title, wp_posts.post_content) AGAINST ('*' IN BOOLEAN MODE)` (filtros `posts_search` + `posts_search_orderby`/`posts_clauses`), ordenando por relevancia cuando no se pida otro orden. Sanitiza el término. Si falla/no aplica, deja el comportamiento nativo (degradación elegante). Debe **convivir** con los filtros del punto 3 (autor, cat, date, meta) sin romper el WHERE. ### 2. Formulario de búsqueda avanzada - mu-plugin **`fea-search-advanced.php`** que renderiza un formulario (method=get, action a la raíz del idioma como en `fea-search.php`) con: - texto `s` (palabra/frase), - `` (categorías TEMA: 1650 Artículos, 1647 Comentarios al evangelio, 1648 Eucaristía, 1649 Multimedia, 1645 Lecturas, 1646 Comentario editorial, 63 EFFA — usa slugs/ids reales; excluye las de carta 6/21/22), - texto `fea_cita` (cita bíblica, ej. «Jn 3» o «Mt»), - fechas `fea_date_from` / `fea_date_to` (o año desde/hasta). - Muéstralo en la página de resultados (template search) arriba, con los valores seleccionados persistentes. Añade un enlace «Búsqueda avanzada» desde la barra `fea-search`. - Considera una página dedicada `/buscar` (page slug `buscar`) que muestre el formulario aunque no haya consulta aún (opcional pero recomendable como destino del enlace). ### 3. Aplicar filtros — `pre_get_posts` En el mismo mu-plugin, registra las query vars (`query_vars` filter) y en `pre_get_posts` (`is_search`, main query, !admin): - `fea_author` → `$q->set('author', (int))`. - `fea_cat` → `$q->set('cat', (int))`. - `fea_cita` → `meta_query` `[['key'=>'_cita_evangelio','value'=>$cita,'compare'=>'LIKE']]` (el sitio ya tiene 4.290 metas `_cita_evangelio`). - `fea_date_from`/`fea_date_to` → `date_query`. Combinables entre sí y con la palabra (FULLTEXT). Si solo se pasan filtros sin `s`, debe funcionar igual (listado filtrado). ### 4. UI de resultados - Reutiliza el template `search` (rejilla `fea-archive-card`). Añade el **autor** en cada tarjeta (byline corto) y, arriba, el formulario del punto 2 + un «N resultados» + chips de filtros activos. Mantén la estética del sitio (carmesí #8b1a2e). ### 5. Multiidioma - Polylang filtra por idioma (no fuerces `lang`). Action del form a la raíz del idioma actual. - Categorías: usa las traducidas vía Polylang cuando el idioma ≠ es. Autores: los mismos. - Textos de la UI (labels, placeholder) por idioma (array es/en/fr/it/pt; al menos es/en). ## Verificación (en local, OBLIGATORIA antes de entregar) Usa la suite Playwright (`tools/e2e`, scripts `shot_*.cjs`; ejecuta con `NODE_PATH=tools/e2e/node_modules node tools/e2e/