Astro per sviluppatori WordPress

In questa pagina

Astro fornisce le pagine, i layout, i componenti e il rendering lato server di un sito EmDash. Questa guida tratta i concetti di Astro usati dai template EmDash attuali. Presuppone che tu comprenda già i temi WordPress e i template PHP.

Per le funzionalità del framework che non sono specifiche di EmDash, consulta la documentazione di Astro.

Struttura del progetto

Un sito Astro assegna una directory esplicita a ogni tipo di file. I template EmDash attuali usano questa struttura:

WordPressAstroScopo
index.php, single.php, page.phpsrc/pages/Route URL
template-parts/src/components/Markup riutilizzabile
header.php e footer.phpsrc/layouts/Strutture di pagina condivise
style.csssrc/styles/Stili del sito
Configurazione di plugin e databaseastro.config.mjsIntegrazioni e adattatore server
Dati di configurazione del temaseed/seed.jsonCollezioni, menu e contenuti di esempio

Il template del blog usa directory di route che corrispondono ai suoi URL pubblici:

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

Componenti Astro

Un componente .astro combina TypeScript lato server e un template HTML. Il codice tra i delimitatori --- viene eseguito sul server. Il markup sotto il secondo delimitatore diventa l’HTML della risposta.

Il seguente componente dichiara le props nel proprio frontmatter e le renderizza nel proprio 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>

Astro esegue l’escape dei valori renderizzati con {value}. Import, query al database e altre operazioni lato server vanno nel frontmatter.

Espressioni nei template

I template Astro usano le parentesi graffe dove un template PHP passerebbe a <?php ?>. Gli schemi più comuni nei template EmDash sono valori, condizioni e mappatura di array:

ObiettivoSintassi Astro
Stampare un valore{post.data.title}
Renderizzare quando esiste un valore{post.data.excerpt && <p>{post.data.excerpt}</p>}
Scegliere tra due risultati{posts.length === 0 ? <p>No posts yet.</p> : <PostList />}
Renderizzare un elenco{posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)}

L’espressione può usare variabili preparate nel frontmatter, valori di Astro.props o dati restituiti da una query di EmDash. Astro esegue di default l’escape dei valori stringa; usa un renderer come <PortableText /> per il rich text strutturato invece di iniettare HTML.

Props e slot

Le props sono paragonabili agli $args passati a get_template_part(). Rendono esplicito ogni input e possono essere controllate da TypeScript.

Gli slot permettono a un genitore di passare markup a un componente. Uno slot di default è utile per il contenuto della pagina, mentre gli slot con nome offrono punti di inserimento aggiuntivi:

---
interface Props {
  title: string;
}

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

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

La pagina seguente riempie entrambi gli slot:

---
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>

Gli slot sono locali alla chiamata del componente. Non si comportano come le action di WordPress, che possono ricevere callback registrate altrove.

Layout

Un layout possiede la struttura di documento condivisa che un tema WordPress spesso divide tra header.php e footer.php. Le pagine importano il layout e passano il proprio contenuto attraverso il suo slot.

Il seguente layout fornisce una struttura di 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>

La pagina seguente fornisce il titolo e il contenuto principale del layout:

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

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

Routing basato su file

I file in src/pages/ definiscono le route. I nomi di file tra parentesi quadre creano segmenti dinamici.

FileURL
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

All’interno di src/pages/posts/[slug].astro, Astro.params.slug contiene il valore preso dall’URL. Leggi Routing in Astro per i parametri rest, i reindirizzamenti e le altre funzionalità di routing.

Rendering lato server

I template EmDash attuali usano output: "server" in astro.config.mjs. Una pagina può quindi interrogare il database a ogni richiesta, così i contenuti pubblicati non dipendono da una nuova build statica.

Non aggiungere getStaticPaths() alla route di un tema EmDash, a meno che il sito non tratti deliberatamente EmDash come origine dati in fase di build. I temi forniti vengono renderizzati lato server.

Leggi Rendering on-demand in Astro per il comportamento a livello di framework.

Interrogare i contenuti EmDash

EmDash avvolge le collezioni di contenuti live di Astro con getEmDashCollection() e getEmDashEntry(). I risultati di una collezione contengono un array entries. I risultati di una singola voce contengono entry, che è null quando nessuna voce pubblicata corrisponde.

Il seguente archivio usa lo stesso ordinamento e gli stessi identificatori del template del blog attuale:

---
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 è l’identificatore di route esposto da Astro e normalmente è lo slug della voce. post.data.id è l’identificatore del database. Usa data.id quando un’API si aspetta l’ID del contenuto memorizzato, come negli helper per tassonomie o commenti.

La seguente route dinamica cerca un articolo in base allo slug nell’URL e ne renderizza il 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>

Continuare con Astro

I template EmDash usano anche stili dei componenti e piccoli script del browser, ma sono normali funzionalità di Astro e non concetti di EmDash. Leggi Stili e CSS per gli stili con ambito e globali, e Script e gestione degli eventi quando un componente ha bisogno di comportamento lato browser.