Communitygithub.com

sijad/astro-wordpress

Convierte una plantilla estática de Astro en un tema de WordPress mediante el adaptador astro-wordpress: instala el adaptador, configura astro.config.mjs, añade el style.css del tema, convierte las páginas a .php.astro y, opcionalmente, ejecuta WordPress con Docker Compose.

¿Qué es astro-wordpress?

Este skill ofrece una receta verificada para transformar cualquier sitio estático de Astro en un tema funcional de WordPress utilizando el adaptador `astro-wordpress`. A diferencia de una simple traducción del README, aquí se detalla un proceso probado de extremo a extremo: desde la instalación del adaptador y la configuración de `astro.config.mjs` (con soporte tanto para WordPress local como en Docker), hasta la conversión de páginas a `*.php.astro` y la activación del tema. Incluye además opciones avanzadas como la ejecución de WordPress mediante Docker Compose (sin necesidad de PHP/MySQL local) y comandos alternativos sin `wp-cli`. El skill cubre exclusivamente la configuración base del adaptador; para hacer que el contenido sea editable desde el backoffice de WordPress con ACF, se debe consultar el skill complementario `astro-wordpress-acf`. Es ideal para desarrolladores que necesiten migrar rápidamente un prototipo de Astro a un ecosistema WordPress sin perder las ventajas del desarrollo con Astro.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sijad/astro-wordpress/tree/HEAD/skills/astro-wordpress

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Convierte una plantilla estática de Astro en un tema de WordPress mediante astro-wordpress: las páginas en src/pages/*.php.astro se compilan a archivos de plantilla reales de WordPress (index.php, page-template-*.php, …), mientras que npm run dev redirige a través de una instancia local real de WordPress para que el tema siempre se previsualice en vivo contra ella.

Esta es la receta verificada, no una paráfrasis del README del adaptador: los pasos siguientes se aplicaron a una plantilla estática de Astro real y se confirmaron de punta a punta: el servidor de desarrollo redirige en vivo a través de WordPress, npm run build produce un tema activable real, wp theme activate funciona correctamente.

Prerrequisitos

  • Una instalación local de WordPress accesible por HTTP. Dos opciones verificadas:
    • Docker Compose (recomendada: no requiere PHP/MySQL/wp-cli local en absoluto, y es posible que wp-cli no esté instalado en el host). Ver paso 0.
    • Una instalación local de WP ya en funcionamiento (cualquier servidor PHP + MySQL/MariaDB apuntado por devProxyTarget). Este skill solo convierte el lado de Astro en cualquier caso.
  • Node/npm para el proyecto Astro.
  • wp-cli es opcional en todo este skill — cada comando wp-cli que aparece a continuación tiene una alternativa sin wp-cli (envío de formularios por navegador/curl, o un sidecar wp-cli dockerizado). No lo añadas como requisito obligatorio.

0. (Opción Docker) Iniciar WordPress con Docker Compose

Este compose.yaml exacto (del starter astro-wordpress) funciona sin modificaciones — verificado ejecutándolo realmente:

services:
  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8088:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wp:/var/www/html
      - ./public/:/var/www/html/public

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: "1"
    volumes:
      - db:/var/lib/mysql

volumes:
  db:
docker compose up -d

No hay wp-cli en la imagen wordpress por defecto: completa la instalación y todo lo demás ya sea a través del navegador (http://localhost:8088), o con un contenedor wp-cli dockerizado de un solo uso que comparta la misma red + volúmenes (ver Verificación/Problemas — este es el patrón a utilizar cada vez que un paso siguiente diga wp ... y no haya wp-cli local instalado):

docker run --rm --network container:<nombre-contenedor-wordpress> \
  --volumes-from <nombre-contenedor-wordpress> -w /var/www/html \
  -e WORDPRESS_DB_HOST=db -e WORDPRESS_DB_USER=exampleuser \
  -e WORDPRESS_DB_PASSWORD=examplepass -e WORDPRESS_DB_NAME=exampledb \
  wordpress:cli <comando-wp-cli>

(Las variables -e deben coincidir con el entorno del servicio wordpress — el contenedor CLI lee el mismo wp-config.php, que las resuelve mediante getenv(), pero no hereda el entorno del otro contenedor).

Pasos

1. Instalar el adaptador

npm install astro-wordpress

(passthroughImageService que se usa más abajo viene incluido con Astro core — no se necesita ningún paquete adicional).

2. Configurar astro.config.mjs

WP directo (Astro y WP en el mismo host, sin límite de contenedor):

// @ts-check
import { defineConfig, fontProviders, passthroughImageService } from "astro/config";
import wordpress from "astro-wordpress";

export default defineConfig({
  server: {
    host: "127.0.0.1",
  },
  adapter: wordpress({
    devProxyTarget: "http://localhost:7001", // tu URL local de WP
    outDir: "./wp/wp-content/themes/<nombre-del-tema>", // el tema compilado va aquí
  }),
  image: {
    service: passthroughImageService(), // requerido — WP sirve/optimiza las imágenes por sí mismo
  },
});

WP con Docker Compose (usando el compose.yaml de arriba) necesita tres opciones más — cada una verificada como necesaria al fallar realmente sin ellas (ver Problemas):

export default defineConfig({
  server: {
    host: "0.0.0.0", // vincular en todas las interfaces para que el contenedor pueda alcanzarlo
    allowedHosts: ["host.docker.internal"],
  },
  adapter: wordpress({
    devProxyTarget: "http://localhost:8088",
    outDir: "./wp/wp-content/themes/<nombre-del-tema>",
    // la propia vista del contenedor WP del directorio public/ montado por bind —
    // NO la ruta del host (ver Problemas)
    publicDirPath: "/var/www/html/public",
    // permite que el stub de la plantilla de desarrollo PHP, ejecutándose *dentro*
    // del contenedor, se comunique de vuelta con el servidor de desarrollo de Astro
    // que se ejecuta en el host
    devServerTarget: "http://host.docker.internal:4321",
  }),
  image: { service: passthroughImageService() },
});

devProxyTarget debe coincidir con donde sea que WordPress esté realmente escuchando. outDir es donde npm run build escribe el tema terminado; no es necesario que esté dentro del proyecto Astro. Si lo está (un checkout local completo de WP anidado bajo, p.ej., ./wp/), añade ese directorio a .gitignore — el núcleo de WordPress y sus subidas no pertenecen al repositorio del proyecto Astro.

3. Añadir la hoja de estilo del tema

WordPress solo reconoce un directorio de tema si tiene un style.css con esta cabecera: crea public/style.css (el adaptador lo enlaza/copia automáticamente en outDir):

/*!
Theme Name: <Nombre del Tema>
Version: 0.0.1
*/

4. Convertir páginas a .php.astro

Renombra cada ruta src/pages/*.astro que quieras que WordPress sirva a src/pages/*.php.astro — la exportación por defecto del archivo sigue renderizándose a través de Astro/tus layouts y componentes existentes sin cambios; solo cambian la extensión y el formato de salida final (index.astro → index.php). No se requieren otros cambios de código para que una página se compile y sirva correctamente.

Los archivos de plantilla no index de WP siguen el mismo patrón: el prefijo page-template- se detecta automáticamente y se convierte en un comentario /* Template Name: ... */ que WordPress reconoce para plantillas de página personalizadas, p.ej. src/pages/page-template-landing.php.astro → una plantilla "Landing" seleccionable. (Documentado en el README del adaptador; no se ha probado en esta receta).

Para archivos que deben generar PHP sin procesar sin documento HTML circundante (p.ej., un functions.php.astro usado para registrar hooks/campos — consulta el skill astro-wordpress-acf), añade export const partial = true; en el frontmatter. Sin él, Astro antepone automáticamente <!DOCTYPE html> a la salida y corrompe el archivo PHP.

5. Activar el tema

Universalmente: Administración de WP → Apariencia → Temas → Activar. Con wp-cli (local o dockerizado, ver paso 0):

npm run build
wp theme activate <nombre-del-tema> --path=<directorio-wp>

Verificar

# 1. ¿Servidor de desarrollo y WP funcionando? cada solicitud se redirige a devProxyTarget,
#    por lo que incluso los activos estáticos dan 502 si WP no es accesible
npm run dev &
curl -o /dev/null -s -w "%{http_code}\n" http://127.0.0.1:4321/

# 2. omitir el proxy de WP para ver la salida sin procesar renderizada por Astro con sabor a PHP
#    directamente desde el servidor de desarrollo — útil para aislar "¿es un problema de Astro
#    o de WordPress?"
curl -s -H "by-pass-proxy: 1" http://127.0.0.1:4321/index.php | head -c 300

# 3. la compilación de producción coloca PHP real y sin procesar en outDir
npm run build
grep -c '<?php' wp/wp-content/themes/<nombre-del-tema>/index.php

# 4. el tema está activo — mediante wp-cli, o simplemente carga la página principal y comprueba
#    si hay marcado específico del tema en lugar de wp-cli
wp theme list --path=<directorio-wp> | grep <nombre-del-tema>

¿Aún no tienes una instalación local de WP para probar y quieres confirmar que la instalación de WP funciona sin interfaz gráfica (sin wp-cli, sin navegador)? El asistente de instalación es un formulario POST simple — así es exactamente como se verificó una instalación nueva de WP para este skill:

curl "http://localhost:8088/wp-admin/install.php?step=2" \
  --data-urlencode "weblog_title=Mi Sitio" \
  --data-urlencode "user_name=admin" \
  --data-urlencode "admin_password=<contraseña>" \
  --data-urlencode "admin_password2=<contraseña>" \
  --data-urlencode "pw_weak=1" \
  --data-urlencode "[email protected]" \
  --data-urlencode "Submit=Instalar WordPress"
# luego inicia sesión de la misma manera (cookie jar) para cualquier comprobación
# posterior en la pantalla de administración:
curl -c cookies.txt \
  --data-urlencode "log=admin" --data-urlencode "pwd=<contraseña>" \
  --data-urlencode "wp-submit=Iniciar Sesión" \
  --data-urlencode "redirect_to=http://localhost:8088/wp-admin/" \
  --data-urlencode "testcookie=1" \
  "http://localhost:8088/wp-login.php"
curl -b cookies.txt "http://localhost:8088/wp-admin/" | grep -o "<title>[^<]*</title>"

Problemas comunes

  • Cada solicitud en modo desarrollo se redirige a devProxyTarget, no solo las páginas .php — /src, /@, /node_modules y cualquier cosa con una cabecera by-pass-proxy son las únicas excepciones. Si WordPress no está funcionando, todo el sitio da 502, incluyendo imágenes/fuentes en public/. Comprueba que WP esté realmente activo antes de depurar el lado de Astro.
  • El servidor de desarrollo de Astro 7 es un demonio persistente en segundo plano. Ejecutar npm run dev una segunda vez no reasigna ni da error — simplemente informa de la instancia ya en ejecución (npx astro dev status / stop / logs para gestionarlo directamente).
  • export const partial = true; — ver paso 4. Este es el requisito menos obvio de todo el adaptador; el modo de fallo (un <!DOCTYPE html> suelto al principio de un archivo PHP) no parece estar relacionado con Astro en absoluto.
  • publicDirPath debe ser la ruta tal como la ve el contenedor de WP, no la ruta del host. El adaptador enlaza simbólicamente cada archivo de public/ al directorio del tema usando el publicDirPath que le proporciones, literalmente. Con Docker, asígnale la ruta del contenedor (/var/www/html/public) — confirmado comprobando el enlace simbólico resultante en ambos sentidos: readlink wp-content/themes/<tema>/style.css → /var/www/html/public/style.css, que se resuelve bien mediante docker exec <contenedor> cat wp-content/themes/<tema>/style.css pero da No such file or directory desde el shell del host. Si omites publicDirPath, el adaptador utiliza la ruta del host, que no es válida dentro del contenedor.
  • El bloqueo del demonio de astro dev es por directorio de proyecto, no por configuración/puerto. Ejecutar astro dev --config other.config.mjs --port 4325 mientras un astro dev simple ya se está ejecutando en el mismo directorio simplemente muestra "El servidor de desarrollo ya está en ejecución" en el puerto original — no inicia una segunda instancia. Ejecuta astro dev stop en la instancia existente primero si necesitas cambiar de configuración (p.ej., directo vs. Docker) en el mismo proyecto.
  • Esta conversión por sí sola no conecta wp_head()/wp_footer() en el layout, por lo que las etiquetas <script>/<style> inyectadas por plugins, las metaetiquetas de plugins SEO, etc., no aparecerán. El README de astro-wordpress muestra cómo añadir <Fragment set:html={} /> / <?php wp_footer(); ?> al layout para eso. Si el layout construye su propio <head> de forma independiente (común al portar una plantilla estática existente), trata la conexión de esos elementos como una tarea posterior deliberada, no algo que los pasos de este skill ya te proporcionen.
  • astro check (parte de npm run build) puede fallar por falta de memoria al intentar verificar tipos de los archivos centrales de WordPress que llegan a ./wp una vez que el contenedor se inicia (miles de archivos .js/.php bajo wp-includes/js/dist/, etc.). Añade "exclude": ["dist", "wp"] a tsconfig.json antes de ejecutar una compilación con Docker WP ya activo; de lo contrario, el fallo parece un cuelgue de Node sin relación alguna con el adaptador de WordPress.
  • Biome (o cualquier linter/formateador que se ejecute sobre todo el repo) también intentará procesar ./wp una vez que exista, por la misma razón: añade una entrada de ignorado (p.ej., "files": { "ignore": ["wp/**"] } en biome.json) antes de ejecutar el comando de lint/formateo del proyecto.
  • Las rutas con parámetros rest dinámicos no se convierten. src/pages/blog/[...slug].astro (o cualquier [...x].astro) no puede convertirse en [...x].php.astro — el enrutador de Astro lo rechaza directamente ("el parámetro rest debe ser un segmento independiente") porque el sufijo .php rompe el límite del segmento. Deja esas rutas como .astro simples y fuera del tema de WP, a menos que el contenido mismo se esté migrando a WP.

Siguiente paso

Una vez que el adaptador esté conectado:

  • astro-wordpress-acf — haz que secciones específicas de una página sean editables desde el backoffice de WP mediante ACF.
  • astro-wordpress-menus — conecta un componente de encabezado/pie de página/navegación a un menú gestionado por WordPress (Apariencia → Menús) en lugar de enlaces fijos.
  • astro-wordpress-global-settings — añade una página de "Opciones del tema" para todo el sitio con valores que no estén limitados a una sola página (requiere ACF Pro o Secure Custom Fields).

Skills relacionados