Co-authored-by: rafa <rcalvotorrejon@gmail.com> Signed-off-by: rafa <rcalvotorrejon@gmail.com>
21 KiB
Guía para publicar la carta semanal en Fe Adulta (WordPress)
Para quién es este documento: para el asistente (Claude Code / Cowork) que ayuda a Inma a publicar la carta semanal y los artículos en el WordPress nuevo de Fe Adulta.
Reparto de responsabilidades:
- Inma aporta el contenido editorial: cómo se redacta y compone la carta y los artículos.
- Este documento aporta la infraestructura y la estructura del sitio: cómo conectarse, dónde va cada cosa, qué categorías usar, qué se publica automáticamente y qué hay que hacer a mano.
- Inma sube siempre en ESPAÑOL. Las traducciones (EN/FR/IT/PT) y el audio (TTS) los genera un proceso automático en el servidor (ver §7). No hay que traducir a mano.
1. El sitio y cómo conectarse
1.1 Entornos
| Entorno | URL | Estado |
|---|---|---|
| Producción | https://www.feadulta.com |
El sitio en vivo, WordPress. Cutover completado el 2026-07-08 |
| Legado Joomla | https://antiguo.feadulta.com |
Solo contenido histórico no migrado. No se publica aquí |
El cutover de dominio ya se hizo (2026-07-08): www.feadulta.com es WordPress y es donde
se publica siempre. wp-nuevo.feadulta.com (el subdominio de Beta) ha dejado de servir nada
(el directorio que usaba se vació al mover los ficheros a la raíz del hosting) — si algún
enlace o script antiguo todavía lo menciona, hay que cambiarlo a www.feadulta.com.
1.2 Acceso recomendado: API REST de WordPress + contraseña de aplicación
No hace falta SSH ni tocar la base de datos. WordPress trae una API REST y un sistema de "Contraseñas de aplicación" (Application Passwords) pensado exactamente para esto.
Cómo obtener la credencial (lo hace Inma una sola vez): Inma ya tiene usuario con rol Editor en el sitio (suficiente para crear, editar, publicar y programar entradas). Con ese usuario:
- Entrar en
https://www.feadulta.com/wp-admin. - Ir a Usuarios → Perfil → bajar hasta "Contraseñas de aplicación".
- Escribir un nombre (p. ej.
cowork-cartas) y pulsar Añadir. - WordPress muestra una contraseña de 24 caracteres con espacios
(formato
xxxx xxxx xxxx xxxx xxxx xxxx). Se copia y se guarda: solo se ve una vez.
Cómo la usa el asistente: autenticación HTTP Basic sobre HTTPS, con
usuario:contraseña_de_aplicación. Ejemplo de prueba (debe responder con los datos del
usuario):
curl -s -u "USUARIO:xxxx xxxx xxxx xxxx xxxx xxxx" \
https://www.feadulta.com/wp-json/wp/v2/users/me
Base de la API para todo lo demás: https://www.feadulta.com/wp-json/wp/v2/
⚠️ Pendiente de configurar en Cloudflare (bloqueante). Comprobado el 27/06/2026: el sitio está tras Cloudflare y devuelve 403 "Attention Required" a cualquier petición que no sea un navegador real con JavaScript — afecta a la API REST, a la home y a
wp-login.php, incluso enviando un User-Agent de navegador. Es el reto de navegador de Cloudflare, no un problema de la credencial.Para que el asistente pueda usar la API hay que crear una excepción en el panel de Cloudflare (lo hace Inma). Opciones, de más simple a más limpia:
- Allowlist por IP de origen: WAF → Tools → permitir la IP pública desde la que se conecta el asistente. Simple, pero requiere IP fija/conocida.
- Regla WAF con token secreto: una Custom Rule que haga Skip / Bypass cuando la petición vaya a
/wp-json/*y lleve una cabecera secreta (p. ej.X-FEA-Key: <secreto>). El asistente añade esa cabecera en cada llamada.- Subdominio "solo DNS" (sin proxy naranja), p. ej.
api.feadulta.com, apuntando al mismo origen para servir la API sin pasar por el reto de Cloudflare.Hasta que se aplique una de estas, las llamadas a la API fallarán con 403. Coordinar con Rafa/Inma cuál se elige.
2. La idea clave: la carta de la semana ES la portada
Esto es lo más importante de entender. La portada de Fe Adulta no muestra "los últimos artículos por categoría". Muestra exactamente lo que enlaza la carta de la semana actual, agrupado por las secciones internas de esa carta.
Es decir: la carta semanal es un artículo largo en HTML, con secciones marcadas por encabezados, y dentro de cada sección hay enlaces a otros artículos. La portada lee la carta vigente, detecta esas secciones y coloca cada grupo de enlaces en su bloque correspondiente.
Consecuencia práctica: para que la portada se rellene bien, la carta tiene que estar escrita con unos encabezados de sección concretos (§5) y enlazar a artículos que ya existan en el sitio (§4).
3. Categorías del sitio
Las categorías se asignan por su ID numérico vía API (campo categories: [..]).
3.1 Categorías de la carta (estado de cada carta)
| ID | Nombre | Slug | Significado |
|---|---|---|---|
| 6 | Carta de la semana | cartasemana |
La carta vigente. Debe estar solo la actual. |
| 22 | La semana pasada | carta-semana-pasada |
La carta de la semana anterior. Debe estar solo una. |
| 21 | Cartas de otras semanas | cartas-de-otras-semanas |
Histórico acumulativo: TODAS las cartas publicadas alguna vez, incluidas la vigente (6) y la anterior (22). No se quita nunca, solo se añade. Así el listado de "Otras Semanas" sirve para navegar por cualquier carta pasada sin tener que ir carta por carta. |
3.2 Categorías temáticas (para los artículos de dentro de la carta)
| ID | Nombre | Uso |
|---|---|---|
| 1645 | Lecturas bíblicas | Lecturas del domingo |
| 1646 | Comentario editorial | Comentario editorial de la semana |
| 1647 | Comentarios al evangelio | Artículos que comentan el evangelio |
| 1648 | Eucaristía | Material para la eucaristía |
| 1649 | Multimedia | Vídeos / audios / material multimedia |
| 1650 | Artículos | Artículos generales seleccionados |
Cada artículo de la semana va en su categoría temática. La carta (el texto largo) va en la categoría 6.
4. Cómo se publica una carta nueva (flujo completo)
Una "carta" no es un solo artículo: es un artículo-carta que enlaza a varios artículos. El orden correcto es: primero los artículos, luego la carta que los enlaza.
Paso 1 — Crear los artículos de la semana
Cada pieza de contenido (cada comentario al evangelio, cada artículo seleccionado, etc.) es un post propio. Se crean vía API y conviene crearlos primero como borrador y, cuando estén listos, publicarlos.
curl -s -u "USUARIO:APP_PASSWORD" \
-X POST https://www.feadulta.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-d '{
"title": "Título del artículo",
"content": "<p>Cuerpo en HTML…</p>",
"status": "draft",
"categories": [1647]
}'
De la respuesta JSON interesan dos campos:
id→ identificador del post.link→ la URL pública del artículo. Guardar esta URL: es la que se usa para enlazar desde la carta.
Repetir para cada artículo, usando la categoría temática que corresponda (§3.2).
⚠️ No adivinéis la URL a partir del título — usad siempre el
linkreal de la API, y solo DESPUÉS de publicar. En la carta 734 los artículos se quedaron endraftcon el título prefijado[PRUEBA], y la carta se compuso enlazando slugs adivinados a mano (.../prueba-silencio/, etc.) a partir de ese título provisional. Al publicar de verdad con el título limpio, WordPress genera el slug desde el título final y le añade un sufijo (-2,-4…) si ya existe otro post con ese mismo slug — algo frecuente en temas recurrentes ("Silencio", "La palabra", "Te encontré"…). Resultado: 21 de 22 enlaces de la carta apuntaban a una URL que nunca existió. Regla: publicad cada artículo (quitando[PRUEBA]del título) en cuanto esté listo, y componed los enlaces de la carta con ellinkque devuelve la API tras ese publish, no antes.
Paso 1.5 — Asignar _carta_id a cada artículo de la semana (IMPORTANTE)
Cada artículo de la semana debe llevar el meta _carta_id = ID del post de la carta a la
que pertenece. Sin esto, el sistema no puede localizar "todos los artículos de esta
carta" para publicarlos/traducirlos/locutarlos en bloque.
_carta_id es un meta interno y no se puede asignar por el endpoint estándar
/wp/v2/posts/<id> (WordPress lo bloquea por empezar por _). Para esto hay un
endpoint REST propio, desplegado el 2026-07-07:
# Leer el _carta_id actual de un artículo
curl -s -u "USUARIO:APP_PASSWORD" \
https://www.feadulta.com/wp-json/fea/v1/carta-id/ID_DEL_ARTICULO
# Asignar (o corregir) el _carta_id de un artículo
curl -s -u "USUARIO:APP_PASSWORD" \
-X POST https://www.feadulta.com/wp-json/fea/v1/carta-id/ID_DEL_ARTICULO \
-H "Content-Type: application/json" \
-d '{"carta_id": ID_DE_LA_CARTA}'
# Borrar el _carta_id (si os habéis equivocado de artículo)
curl -s -u "USUARIO:APP_PASSWORD" \
-X DELETE https://www.feadulta.com/wp-json/fea/v1/carta-id/ID_DEL_ARTICULO
Respuesta en los tres casos: {"post_id": ID, "carta_id": ID|null}.
Notas:
- Solo podéis asignar
_carta_ida artículos que ya podéis editar (mismo criterio que el resto de la API: vuestro usuario Editor). carta_idtiene que ser el ID de un post que exista (normalmente el de la carta, aunque en el momento de llamar a este endpoint la carta puede que aún esté en borrador — eso no importa, solo tiene que existir el post).- Podéis llamarlo justo después de crear cada artículo (Paso 1) o al final, después de tener
el ID de la carta (Paso 3) — el orden entre pasos 1 y 1.5 y 3 no importa mientras al acabar
todos los artículos de la semana tengan el
_carta_idcorrecto. - Código fuente:
wp-content/mu-plugins/fea-carta-id-api.php(mu-plugin, activo siempre).
Paso 2 — Componer el artículo-carta
La carta es un post HTML con:
- Texto editorial libre (introducción).
- Una sección por cada bloque, encabezada con una de las frases exactas de §5.
- Dentro de cada sección, enlaces (
<a href>) a las URLs de los artículos del Paso 1.
Ver §5 para el formato exacto de los encabezados y un ejemplo completo.
Paso 3 — Publicar (o programar) la carta
La carta va en la categoría 6 (cartasemana) y también en la 21 (cartas-de-otras-semanas)
desde el primer momento — ver §3.1: la 21 es un histórico acumulativo que no se quita nunca, así
que toda carta la lleva ya desde que se crea, no solo cuando se "degrada" en el Paso 4.
- Publicar ya:
"status": "publish". - Programar:
"status": "future"+"date"con la fecha/hora local del sitio en formato ISO 8601, p. ej."2026-06-29T08:00:00". WordPress la publicará sola a esa hora.
curl -s -u "USUARIO:APP_PASSWORD" \
-X POST https://www.feadulta.com/wp-json/wp/v2/posts \
-H "Content-Type: application/json" \
-d '{
"title": "Carta de la semana — 29 de junio",
"content": "<p>…cuerpo de la carta con sus secciones y enlaces…</p>",
"status": "future",
"date": "2026-06-29T08:00:00",
"categories": [6, 21]
}'
Paso 4 — Rotar la carta anterior (IMPORTANTE, manual)
Al entrar una carta nueva en la categoría 6, hay que degradar la anterior para que la categoría "Carta de la semana" contenga solo una carta. Esto es solo mover el marcador de estado (6 → 22 → ninguno): la categoría 21 ("Otras semanas") no se toca en la rotación, porque es acumulativa y ya la lleva cada carta desde que se publicó (Paso 3). Nunca se quita la 21 a una carta.
- A la carta que dejaba de ser actual: quitarle la categoría 6 y ponerle la 22 ("La semana pasada"). Mantiene la 21 que ya tenía.
- A la que estaba en 22: quitarle la 22 sin más. Mantiene la 21 que ya tenía — así queda solo en el histórico "Otras semanas", visible igual que todas las demás.
Vía API se actualiza el array categories del post (sustituye al anterior, así que hay que
incluir siempre la 21 en el array nuevo o se perdería):
# 1. La carta que deja de ser actual: 6 → 22 (conserva 21)
curl -s -u "USUARIO:APP_PASSWORD" \
-X POST https://www.feadulta.com/wp-json/wp/v2/posts/ID_DE_LA_CARTA_VIEJA \
-H "Content-Type: application/json" \
-d '{"categories": [22, 21]}'
# 2. La que estaba en 22: se queda solo con 21 (y las que no sean de estado, p.ej. 71)
curl -s -u "USUARIO:APP_PASSWORD" \
-X POST https://www.feadulta.com/wp-json/wp/v2/posts/ID_DE_LA_CARTA_MAS_VIEJA \
-H "Content-Type: application/json" \
-d '{"categories": [21]}'
⚠️ El endpoint
POST /wp/v2/posts/IDconcategoriessustituye el array completo, no añade. Antes de rotar, comprobar conGET /wp-json/wp/v2/posts/ID_DE_LA_CARTA?_fields=categoriesqué categorías tiene ya el post (p. ej. si tiene además la 71 "Feadulta") e incluirlas todas en el array nuevo — si no, se pierden categorías sin querer (esto pasó en la carta 733/734, ver issue #159 y #161).Si se programa la carta nueva con
future, esta rotación puede hacerse el mismo día en que se publique. Si surge duda sobre qué carta está en qué categoría, consultar:GET /wp-json/wp/v2/posts?categories=6(debe devolver solo una).
5. Formato de la carta para que la portada la "entienda"
La portada parsea el HTML de la carta buscando encabezados con estas frases (no distingue mayúsculas/acentos, pero el texto debe coincidir). Cada encabezado abre una sección; todos los enlaces que vayan después de ese encabezado (hasta el siguiente) se muestran en el bloque de portada indicado:
| Frase del encabezado en la carta | Bloque de portada |
|---|---|
| Evangelio y comentarios al Evangelio | Evangelio |
| Artículos seleccionados para la semana | Artículos de la semana |
| Para unas eucaristías más participativas y actuales | Eucaristía |
| Material multimedia | Multimedia |
| Escuela EFFA | EFFA |
Reglas:
- Los encabezados se suelen marcar en rojo/negrita (es el estilo histórico), pero lo que importa es que el texto coincida con la frase de la tabla.
- Los enlaces dentro de cada sección deben apuntar a artículos que existan en el sitio (las URLs del Paso 1). Enlaces a páginas externas se ignoran.
- Si una sección no tiene enlaces, ese bloque de la portada queda vacío.
- "Noticias de alcance" NO se enlaza a mano en el cuerpo de la carta. Si la semana incluye una noticia de este tipo, el artículo va categorizado en la categoría 41 ("Noticias de alcance") y eso basta: la portada tiene un bloque de footer aparte que se alimenta solo de esa categoría. Si además se enlaza esa noticia dentro de "Artículos seleccionados para la semana", sale duplicada en la portada (pasó en la carta 734, ver issue #159).
Ejemplo mínimo de cuerpo de carta:
<p>Texto editorial de introducción de la semana…</p>
<p><strong style="color:red">Evangelio y comentarios al Evangelio</strong></p>
<ul>
<li><a href="https://www.feadulta.com/comentario-evangelio-domingo/">Comentario al evangelio</a></li>
</ul>
<p><strong style="color:red">Artículos seleccionados para la semana</strong></p>
<ul>
<li><a href="https://www.feadulta.com/articulo-uno/">Primer artículo</a></li>
<li><a href="https://www.feadulta.com/articulo-dos/">Segundo artículo</a></li>
</ul>
<p><strong style="color:red">Para unas eucaristías más participativas y actuales</strong></p>
<ul>
<li><a href="https://www.feadulta.com/eucaristia-domingo/">Material para la eucaristía</a></li>
</ul>
<p><strong style="color:red">Material multimedia</strong></p>
<ul>
<li><a href="https://www.feadulta.com/video-semana/">Vídeo de la semana</a></li>
</ul>
La portada cachea el resultado 15 minutos. Al guardar/editar la carta se refresca sola, pero si un cambio no se ve al momento, esperar unos minutos.
6. Qué es automático y qué hay que tocar a mano
Automático — NO hay que hacer nada
- Portada (home): se construye sola a partir de la carta vigente (la más reciente en la categoría 6) y sus secciones (§5).
- Página "Carta de la semana" (
/carta-de-la-semana/): redirige automáticamente a la carta más reciente de la categoría 6. - Página "La semana pasada" (
/la-semana-pasada/): redirige a la carta más reciente de la categoría 22. - Menús, avatares de autores, multiidioma, etc.: gestionados por el tema/plugins.
- Traducciones (EN/FR/IT/PT) y audio (TTS): las genera el proceso del servidor (§7).
Manual — lo que hace Inma / su asistente
- Crear los artículos de la semana (§4, Paso 1).
- Componer y publicar/programar la carta (§4, Pasos 2-3).
- Rotar la carta anterior de categoría (§4, Paso 4).
- Subir imagen destacada del artículo si se quiere (campo
featured_mediacon el ID de un adjunto previamente subido a la biblioteca de medios).
7. Traducción y audio (lado servidor — ⚠️ hoy es MANUAL, no automático)
Corregido 2026-07-12: esto todavía NO es automático. El cron que traduciría y generaría audio solo al publicar (issue #23) sigue sin implementar — es una propuesta abierta, no algo que ya corra. Versiones anteriores de esta guía decían "hay (o habrá) un proceso programado" dando a entender que ya estaba activo o a punto; no lo está. Inma NO tiene que traducir ni generar audio ella misma, pero sí tiene que pedirlo — no llega solo.
Cómo pedirlo hoy: escribir al grupo de WhatsApp mencionando "Hermes" (o por Telegram),
indicando la carta/artículo. Hermes ejecuta los scripts correspondientes en el servidor de Rafa.
Ver el runbook completo (motores de traducción, voces TTS por autor, tiempos, qué hacer si
Hermes no responde) en docs/guia-tts-traduccion-inma.md.
Por eso sigue siendo importante subir siempre el contenido en español — la traducción parte siempre del ES, pero hay que pedirla, no asumir que "ya llegará". Si una carta urgente necesita traducción inmediata, avisar a Rafa directamente además de pedírselo a Hermes.
Este punto es responsabilidad de Rafa (infraestructura). Se incluye aquí para que el asistente de Inma sepa que el trabajo de traducir/locutar no lo tiene que hacer él mismo, pero sí que tiene que solicitarlo activamente.
8. Resumen rápido (checklist por carta)
- Crear cada artículo de la semana y publicarlo (no dejarlo en
draft/[PRUEBA]). - Guardar la URL (
link) de cada artículo después de publicarlo, no antes (el slug puede cambiar por colisión con otro post del mismo título). - Asignar
_carta_ida cada artículo con el endpoint de §1.5 (fea/v1/carta-id/{id}). - Componer la carta en HTML con los encabezados exactos de §5 y los enlaces a esos artículos.
- Publicar o programar la carta en las categorías 6 y 21 (§3.1, §4 Paso 3).
- Rotar la carta anterior: quitar 6, poner 22 (conservando su 21). A la que estaba en 22, quitarle solo la 22 (conservando su 21 — nunca se quita la 21 a nadie, §4 Paso 4).
- Comprobar que la portada muestra las secciones (esperar hasta 15 min si hace falta).
- No traducir ni generar audio a mano — pero SÍ pedirlo a Hermes (WhatsApp/Telegram, ver §7 y
docs/guia-tts-traduccion-inma.md). No es automático todavía.
9. Referencia rápida de la API
| Acción | Método y endpoint |
|---|---|
| Probar credencial | GET /wp-json/wp/v2/users/me |
| Listar categorías | GET /wp-json/wp/v2/categories?per_page=100 |
| Crear artículo/carta | POST /wp-json/wp/v2/posts |
| Editar artículo/carta | POST /wp-json/wp/v2/posts/{id} |
| Ver carta vigente | GET /wp-json/wp/v2/posts?categories=6 |
| Subir imagen | POST /wp-json/wp/v2/media (cabecera Content-Disposition) |
Leer _carta_id de un artículo |
GET /wp-json/fea/v1/carta-id/{id} |
Asignar _carta_id a un artículo |
POST /wp-json/fea/v1/carta-id/{id} con body {"carta_id": N} |
Borrar _carta_id de un artículo |
DELETE /wp-json/fea/v1/carta-id/{id} |
Evangelio y comentarios: regla y paso obligatorio para Mixbot
La sección empieza siempre con el enlace al post del evangelio de esa semana (por
ejemplo, MATEO 14, 22-33) y después van los comentarios. Si ese post no existe,
avisad antes de publicar la carta: no empecéis la sección por un comentario.
Primero guarda la carta (puede quedar como borrador) con esa sección ya completa y
anota su ID. Después asigna ese ID a cada comentario al evangelio de la semana con
el endpoint POST /wp-json/fea/v1/carta-id/<id-del-comentario> y el cuerpo
{"carta_id": <id-de-la-carta>}.
No hay que escribir la cita ni el texto bíblico a mano: al asignar _carta_id, el
plugin localiza la única lectura bíblica enlazada en la sección y añade
_cita_evangelio automáticamente, incluso si el comentario ya estaba publicado. Si
la carta tiene cero o varias lecturas, el plugin no adivina: corrige la sección y
vuelve a asignar el ID de carta.
Campos útiles del post: title, content (HTML), status (draft/publish/future),
date (ISO 8601 para programar), categories (array de IDs), featured_media (ID de adjunto).