Communitygithub.com

sijad/astro-wordpress

Converte um template Astro estático em um tema WordPress usando o adaptador astro-wordpress — instale o adaptador, configure o astro.config.mjs, adicione o style.css do tema, converta páginas para .php.astro e, opcionalmente, execute o WordPress via Docker Compose.

O que é astro-wordpress?

Este skill é um guia verificado e passo a passo para transformar qualquer template Astro estático em um tema WordPress funcional, utilizando o adaptador astro-wordpress. Ele cobre desde a instalação do adaptador, configuração do `astro.config.mjs` (incluindo opções específicas para ambientes Docker), criação do `style.css` de tema, conversão de arquivos `.astro` para `.php.astro` (com suporte para `partial = true` em arquivos PHP puros), até a ativação do tema no WordPress. O skill também fornece comandos de verificação (com fallback sem wp-cli), solução de problemas comuns como o proxy do servidor de desenvolvimento, symlinks de `publicDirPath` dentro de contêineres, `<!DOCTYPE html>` indesejado, OOM do `astro check`, e orientação para skills complementares como `astro-wordpress-acf`. É ideal para desenvolvedores que desejam rapidamente dar a um site Astro existente o poder de um CMS WordPress, seja para desenvolvimento local ou implantação em produção.

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

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Transforma um template Astro estático em um tema WordPress via astro-wordpress: páginas em src/pages/*.php.astro compilam para arquivos de template WordPress reais (index.php, page-template-*.php, …), enquanto npm run dev proxy para uma instância WordPress local real, permitindo pré-visualização ao vivo do tema.

Esta é a receita verificada, não uma paráfrase do README do adaptador: os passos abaixo foram aplicados a um template Astro estático real e confirmados de ponta a ponta — servidor de desenvolvimento fazendo proxy para WordPress, npm run build produzindo um tema ativável, wp theme activate executado com sucesso.

Pré-requisitos

  • Uma instalação WordPress local acessível via HTTP. Duas opções verificadas:
    • Docker Compose (recomendado — não requer PHP/MySQL/wp-cli local, e wp-cli pode não estar instalado no host). Veja o passo 0.
    • Uma instalação WP local já em execução (qualquer servidor PHP + MySQL/MariaDB apontado por devProxyTarget). Este skill converte apenas o lado Astro de qualquer forma.
  • Node/npm para o projeto Astro.
  • wp-cli é opcional em todo este skill — todo comando wp-cli abaixo tem uma alternativa sem wp-cli (envio de formulário via navegador/curl, ou um sidecar wp-cli dockerizado). Não o adicione como um requisito obrigatório.

0. (Opção Docker) Iniciar WordPress com Docker Compose

Este compose.yaml exato (do starter astro-wordpress) funciona sem modificações — verificado executando-o:

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

Não há wp-cli na imagem wordpress por padrão — conclua a instalação e todo o resto pelo navegador (http://localhost:8088), ou com um contêiner wp-cli dockerizado descartável compartilhando a mesma rede + volumes (veja Verificar/Armadilhas — este é o padrão a ser usado sempre que um passo abaixo disser wp ... e não houver wp-cli local instalado):

docker run --rm --network container:<wordpress-container-name> \
  --volumes-from <wordpress-container-name> -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 <wp-cli-command>

(As variáveis -e devem corresponder às env do serviço wordpress — o contêiner CLI lê o mesmo wp-config.php, que as resolve via getenv(), mas não herda o ambiente do outro contêiner.)

Passos

1. Instalar o adaptador

npm install astro-wordpress

(passthroughImageService usado abaixo já vem com o Astro core — nenhum pacote extra.)

2. Configurar astro.config.mjs

WP bare-metal (Astro e WP no mesmo host, sem contêiner):

// @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", // sua URL WP local
    outDir: "./wp/wp-content/themes/<theme-name>", // tema construído vai para cá
  }),
  image: {
    service: passthroughImageService(), // obrigatório — WP serve/otimiza imagens por conta própria
  },
});

WP no Docker Compose (usando o compose.yaml acima) precisa de mais três opções — cada uma verificada como necessária ao quebrar sem elas (veja Armadilhas):

export default defineConfig({
  server: {
    host: "0.0.0.0", // escuta em todas as interfaces para o contêiner conseguir acessar
    allowedHosts: ["host.docker.internal"],
  },
  adapter: wordpress({
    devProxyTarget: "http://localhost:8088",
    outDir: "./wp/wp-content/themes/<theme-name>",
    // a visão do próprio contêiner WP do diretório public/ montado por bind —
    // NÃO o caminho do host (veja Armadilhas)
    publicDirPath: "/var/www/html/public",
    // permite que o stub do template de desenvolvimento PHP, executando *dentro*
    // do contêiner, alcance o servidor de desenvolvimento Astro rodando no host
    devServerTarget: "http://host.docker.internal:4321",
  }),
  image: { service: passthroughImageService() },
});

devProxyTarget deve corresponder a onde o WordPress está realmente ouvindo. outDir é onde npm run build escreve o tema finalizado; não precisa estar dentro do projeto Astro. Se estiver (um checkout WP local completo aninhado em, ex., ./wp/), adicione esse diretório a .gitignore — WordPress core e seus uploads não pertencem ao repositório do projeto Astro.

3. Adicionar a folha de estilo do tema

WordPress só reconhece um diretório de tema se ele tiver um style.css com este cabeçalho — crie public/style.css (ele é automaticamente linkado/copiado para outDir pelo adaptador):

/*!
Theme Name: <Nome do Tema>
Version: 0.0.1
*/

4. Converter páginas para .php.astro

Renomeie cada rota src/pages/*.astro que você quer que seja servida pelo WordPress para src/pages/*.php.astro — o export default do arquivo ainda renderiza através dos seus layouts e componentes Astro existentes, sem alterações; apenas a extensão e o formato de saída final mudam (index.astro → index.php). Nenhuma outra mudança de código é necessária para que uma página seja construída e servida corretamente.

Arquivos de template WP que não são index seguem o mesmo padrão: o prefixo page-template- é detectado automaticamente e transformado em um comentário /* Template Name: ... */ que o WordPress reconhece para templates de página personalizados, ex. src/pages/page-template-landing.php.astro → um template "Landing" selecionável. (Documentado no README do adaptador; não testado por esta receita.)

Para arquivos que devem gerar PHP puro sem um documento HTML envolvente (ex.: um functions.php.astro usado para registrar hooks/campos — veja o skill astro-wordpress-acf), adicione export const partial = true; no frontmatter. Sem isso, o Astro automaticamente prefixa <!DOCTYPE html> na saída e corrompe o arquivo PHP.

5. Ativar o tema

Universalmente: Admin WP → Aparência → Temas → Ativar. Com wp-cli (local ou dockerizado, veja passo 0):

npm run build
wp theme activate <theme-name> --path=<wp-dir>

Verificar

# 1. Servidor de desenvolvimento + WP ambos funcionando? toda requisição faz proxy para devProxyTarget,
#    então até assets estáticos retornam 502 se WP não estiver acessível
npm run dev &
curl -o /dev/null -s -w "%{http_code}\n" http://127.0.0.1:4321/

# 2. Ignorar o proxy WP para ver a saída Astro renderizada em PHP diretamente
#    do servidor de desenvolvimento — útil para isolar "é um problema do Astro
#    ou um problema do WordPress"
curl -s -H "by-pass-proxy: 1" http://127.0.0.1:4321/index.php | head -c 300

# 3. A build de produção coloca PHP real e simples em outDir
npm run build
grep -c '<?php' wp/wp-content/themes/<theme-name>/index.php

# 4. Tema ativo — via wp-cli, ou apenas carregue a página inicial e verifique
#    a marcação específica do tema se wp-cli não estiver disponível
wp theme list --path=<wp-dir> | grep <theme-name>

Não tem uma instalação WP local para testar e quer confirmar que a instalação WP funciona sem head (sem wp-cli, sem navegador)? O assistente de instalação é um simples POST de formulário — exatamente assim que uma instalação WP nova foi verificada para este skill:

curl "http://localhost:8088/wp-admin/install.php?step=2" \
  --data-urlencode "weblog_title=Meu Site" \
  --data-urlencode "user_name=admin" \
  --data-urlencode "admin_password=<senha>" \
  --data-urlencode "admin_password2=<senha>" \
  --data-urlencode "pw_weak=1" \
  --data-urlencode "[email protected]" \
  --data-urlencode "Submit=Instalar WordPress"
# então faça login da mesma forma (cookie jar) para quaisquer verificações de tela de admin posteriores:
curl -c cookies.txt \
  --data-urlencode "log=admin" --data-urlencode "pwd=<senha>" \
  --data-urlencode "wp-submit=Log In" \
  --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>"

Armadilhas

  • Toda requisição em modo de desenvolvimento faz proxy para devProxyTarget, não apenas páginas .php — /src, /@, /node_modules e qualquer coisa com cabeçalho by-pass-proxy são as únicas exceções. Se o WordPress não estiver rodando, o site inteiro retorna 502, incluindo imagens/fontes em public/. Verifique se o WP está realmente ativo antes de depurar o lado Astro.
  • O servidor de desenvolvimento do Astro 7 é um daemon persistente em segundo plano. npm run dev uma segunda vez não reata nem gera erro — apenas informa a instância já em execução (npx astro dev status / stop / logs para gerenciá-la diretamente).
  • export const partial = true; — veja passo 4. Este é o requisito mais não óbvio de todo o adaptador; o modo de falha (<!DOCTYPE html> solto no topo de um arquivo PHP) não parece relacionado ao Astro de forma alguma.
  • publicDirPath deve ser o caminho como o contêiner WP o vê, não o caminho do host. O adaptador faz symlink de cada arquivo public/ para o diretório do tema usando exatamente o publicDirPath que você fornecer. Com Docker, forneça o caminho do contêiner (/var/www/html/public) — confirmado verificando o symlink resultante nos dois sentidos: readlink wp-content/themes/<theme>/style.css → /var/www/html/public/style.css, que resolve corretamente via docker exec <container> cat wp-content/themes/<theme>/style.css mas resulta em "Arquivo ou diretório não encontrado" a partir do shell do host. Se você omitir publicDirPath, o adaptador usa o caminho do host, que é inválido dentro do contêiner.
  • O bloqueio do daemon astro dev é por diretório de projeto, não por configuração/porta. Executar astro dev --config other.config.mjs --port 4325 enquanto um astro dev comum já está rodando no mesmo diretório apenas informa "Servidor de desenvolvimento já em execução" na porta original — não inicia uma segunda instância. Use astro dev stop para parar a existente primeiro se precisar trocar de configuração (ex.: bare-metal vs. Docker) no mesmo projeto.
  • Esta conversão sozinha não conecta wp_head()/wp_footer() no layout, então tags <script>/<style> injetadas por plugins, meta tags de plugins SEO, etc., não aparecerão. O README do astro-wordpress mostra como adicionar <Fragment set:html={} /> / <?php wp_footer(); ?> ao layout para isso. Se o layout constrói seu próprio <head> de forma independente (comum ao portar um template estático existente), trate a conexão desses como um acompanhamento deliberado, não algo que os passos deste skill já fornecem.
  • astro check (parte do npm run build) pode travar por OOM ao tentar verificar tipos dos arquivos core do WordPress que caem em ./wp assim que o contêiner inicia (milhares de arquivos .js/.php em wp-includes/js/dist/, etc.). Adicione "exclude": ["dist", "wp"] ao tsconfig.json antes de executar uma build com Docker WP já ativo — caso contrário a falha parece uma quebra de heap do Node não relacionada, sem conexão óbvia com o adaptador WordPress.
  • Biome (ou qualquer linter/formatter executado em todo o repositório) também tentará processar ./wp assim que ele existir, pelo mesmo motivo — adicione uma entrada de ignorar (ex.: "files": { "ignore": ["wp/**"] } em biome.json) antes de executar o comando de lint/format do projeto.
  • Rotas com parâmetros rest dinâmicos não convertem. src/pages/blog/[...slug].astro (ou qualquer [...x].astro) não pode se tornar [...x].php.astro — o roteador do Astro rejeita diretamente ("rest parameter must be a standalone segment") porque o sufixo .php quebra o limite do segmento. Deixe essas rotas como .astro simples e fora do tema WP, a menos que o conteúdo em si esteja sendo migrado para o WP.

Próximo passo

Uma vez que o adaptador esteja configurado:

  • astro-wordpress-acf — torne seções específicas de uma página editáveis a partir do backoffice WP via ACF.
  • astro-wordpress-menus — conecte um componente de cabeçalho/rodapé/navegação a um menu gerenciado pelo WordPress (Aparência → Menus) em vez de links fixos.
  • astro-wordpress-global-settings — adicione uma página de "Opções do Tema" para todo o site com valores que não são específicos de nenhuma página (requer ACF Pro ou Secure Custom Fields).

Habilidades Relacionadas