Astro para desenvolvedores WordPress

Nesta página

O Astro fornece as páginas, os layouts, os componentes e a renderização no servidor de um site EmDash. Este guia aborda os conceitos do Astro usados pelos templates atuais do EmDash. Ele pressupõe que você já entenda temas do WordPress e templates PHP.

Para recursos do framework que não são específicos do EmDash, consulte a documentação do Astro.

Estrutura do projeto

Um site Astro atribui um diretório explícito a cada tipo de arquivo. Os templates atuais do EmDash usam esta estrutura:

WordPressAstroFinalidade
index.php, single.php, page.phpsrc/pages/Rotas de URL
template-parts/src/components/Marcação reutilizável
header.php e footer.phpsrc/layouts/Estruturas de página compartilhadas
style.csssrc/styles/Estilos do site
Configuração de plugins e banco de dadosastro.config.mjsIntegrações e adaptador de servidor
Dados de configuração do temaseed/seed.jsonColeções, menus e conteúdo de exemplo

O template de blog usa diretórios de rotas que correspondem às suas URLs públicas:

src/
├── components/
│   └── PostCard.astro
├── layouts/
│   └── Base.astro
├── pages/
│   ├── index.astro
│   ├── pages/
│   │   └── [slug].astro
│   └── posts/
│       ├── index.astro
│       └── [slug].astro
└── live.config.ts

Componentes Astro

Um componente .astro combina TypeScript do lado do servidor e um template HTML. O código entre os delimitadores --- é executado no servidor. A marcação abaixo do segundo delimitador se torna o HTML da resposta.

O componente a seguir declara props no frontmatter e as renderiza no template:

---
interface Props {
  title: string;
  excerpt?: string;
  href: string;
}

const { title, excerpt, href } = Astro.props;
---

<article>
  <h2><a href={href}>{title}</a></h2>
  {excerpt && <p>{excerpt}</p>}
</article>

O Astro faz o escape dos valores renderizados com {value}. Importações, consultas ao banco de dados e outros trabalhos do servidor pertencem ao frontmatter.

Expressões de template

Os templates Astro usam chaves onde um template PHP mudaria para <?php ?>. Os padrões mais comuns nos templates do EmDash são valores, condições e mapeamento de arrays:

ObjetivoSintaxe do Astro
Imprimir um valor{post.data.title}
Renderizar quando um valor existe{post.data.excerpt && <p>{post.data.excerpt}</p>}
Escolher entre dois resultados{posts.length === 0 ? <p>No posts yet.</p> : <PostList />}
Renderizar uma lista{posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)}

A expressão pode usar variáveis preparadas no frontmatter, valores de Astro.props ou dados retornados por uma consulta do EmDash. O Astro faz o escape de valores de string por padrão; use um renderizador como <PortableText /> para rich text estruturado em vez de injetar HTML.

Props e slots

As props são comparáveis aos $args passados para get_template_part(). Elas tornam cada entrada explícita e podem ser verificadas pelo TypeScript.

Os slots permitem que um pai passe marcação para um componente. Um slot padrão é útil para o conteúdo da página, enquanto os slots nomeados oferecem pontos de inserção adicionais:

---
interface Props {
  title: string;
}

const { title } = Astro.props;
---

<article>
  <h2>{title}</h2>
  <slot />
  <footer><slot name="footer" /></footer>
</article>

A página a seguir preenche os dois slots:

---
import Card from "../components/Card.astro";
---

<Card title="Latest post">
  <p>The main card content.</p>
  <a slot="footer" href="/posts/latest">Read the post</a>
</Card>

Os slots são locais à chamada do componente. Eles não se comportam como as actions do WordPress, que podem receber callbacks registrados em outro lugar.

Layouts

Um layout é responsável pela estrutura de documento compartilhada que um tema do WordPress costuma dividir entre header.php e footer.php. As páginas importam o layout e passam o seu conteúdo por meio do slot dele.

O layout a seguir fornece uma estrutura de documento:

---
interface Props {
  title: string;
}

const { title } = Astro.props;
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>{title}</title>
  </head>
  <body>
    <header><a href="/">My site</a></header>
    <main><slot /></main>
  </body>
</html>

A página a seguir fornece o título e o conteúdo principal do layout:

---
import Base from "../layouts/Base.astro";
---

<Base title="Home">
  <h1>Latest posts</h1>
</Base>

Roteamento baseado em arquivos

Os arquivos em src/pages/ definem as rotas. Nomes de arquivo entre colchetes criam segmentos dinâmicos.

ArquivoURL
src/pages/index.astro/
src/pages/posts/index.astro/posts
src/pages/posts/[slug].astro/posts/hello-world
src/pages/pages/[slug].astro/pages/about

Dentro de src/pages/posts/[slug].astro, Astro.params.slug contém o valor da URL. Leia Roteamento no Astro para ver parâmetros rest, redirecionamentos e outros recursos de roteamento.

Renderização do servidor

Os templates atuais do EmDash usam output: "server" em astro.config.mjs. Por isso, uma página pode consultar o banco de dados a cada requisição, e o conteúdo publicado não depende de um novo build estático.

Não adicione getStaticPaths() a uma rota de tema do EmDash, a menos que o site trate deliberadamente o EmDash como uma fonte de dados em tempo de build. Os temas fornecidos são renderizados no servidor.

Leia Renderização sob demanda no Astro para conhecer o comportamento no nível do framework.

Consultar conteúdo EmDash

O EmDash envolve as coleções de conteúdo ao vivo do Astro com getEmDashCollection() e getEmDashEntry(). Os resultados de uma coleção contêm um array entries. Os resultados de uma única entrada contêm entry, que é null quando nenhuma entrada publicada corresponde.

O arquivo a seguir usa a mesma ordenação e os mesmos identificadores do template de blog atual:

---
import { getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";

const { entries: posts, error } = await getEmDashCollection("posts", {
  orderBy: { published_at: "desc" },
});

if (error) {
  return new Response("Could not load posts", { status: 500 });
}
---

<Base title="Posts">
  {posts.map((post) => (
    <article>
      <h2><a href={`/posts/${post.id}`}>{post.data.title}</a></h2>
      {post.data.excerpt && <p>{post.data.excerpt}</p>}
    </article>
  ))}
</Base>

post.id é o identificador de rota exposto pelo Astro e normalmente é o slug da entrada. post.data.id é o identificador do banco de dados. Use data.id quando uma API esperar o ID de conteúdo armazenado, como nos helpers de taxonomias ou de comentários.

A rota dinâmica a seguir busca um post pelo slug da URL e renderiza o seu campo Portable Text:

---
import { decodeSlug, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "../../layouts/Base.astro";

const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.rewrite("/404");

const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("Could not load the post", { status: 500 });
if (!post) return Astro.rewrite("/404");
---

<Base title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <PortableText value={post.data.content} />
  </article>
</Base>

Continuar com o Astro

Os templates do EmDash também usam estilos de componente e pequenos scripts de navegador, mas esses são recursos comuns do Astro, e não conceitos do EmDash. Leia Estilos e CSS para estilos com escopo e globais, e Scripts e tratamento de eventos quando um componente precisar de comportamento no navegador.