Astro pour les développeurs WordPress

Sur cette page

Astro fournit les pages, layouts, composants et le rendu serveur pour un site EmDash. Ce guide couvre les concepts Astro utilisés par les templates EmDash actuels. Il suppose que vous comprenez déjà les thèmes WordPress et les templates PHP.

Pour les fonctionnalités du framework qui ne sont pas spécifiques à EmDash, utilisez la documentation Astro.

Structure du projet

Un site Astro attribue à chaque type de fichier un répertoire explicite. Les templates EmDash actuels utilisent cette structure :

WordPressAstroObjectif
index.php, single.php, page.phpsrc/pages/Routes URL
template-parts/src/components/Markup réutilisable
header.php et footer.phpsrc/layouts/Structures de page partagées
style.csssrc/styles/Styles du site
Configuration des plugins et de la base de donnéesastro.config.mjsIntégrations et adaptateur serveur
Données de configuration du thèmeseed/seed.jsonCollections, menus et contenu d’exemple

Le template de blog utilise des répertoires de routes qui correspondent à ses URLs publiques :

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

Composants Astro

Un composant .astro combine du TypeScript côté serveur avec un template HTML. Le code entre les délimiteurs --- s’exécute sur le serveur. Le markup sous le second délimiteur devient le HTML de réponse.

Le composant suivant déclare des props dans son frontmatter et les rend dans son 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 échappe les valeurs rendues avec {value}. Les importations, les requêtes de base de données et les autres opérations serveur appartiennent au frontmatter.

Expressions de template

Les templates Astro utilisent des accolades là où un template PHP basculerait vers <?php ?>. Les motifs les plus courants dans les templates EmDash sont les valeurs, les conditions et le mapping de tableaux :

ObjectifSyntaxe Astro
Afficher une valeur{post.data.title}
Rendre quand une valeur existe{post.data.excerpt && <p>{post.data.excerpt}</p>}
Choisir entre deux résultats{posts.length === 0 ? <p>Pas encore d'articles.</p> : <PostList />}
Rendre une liste{posts.map((post) => <PostCard title={post.data.title} excerpt={post.data.excerpt} href={"/posts/" + post.id} />)}

L’expression peut utiliser des variables préparées dans le frontmatter, des valeurs de Astro.props ou des données retournées par une requête EmDash. Astro échappe les valeurs de chaîne par défaut ; utilisez un moteur de rendu comme <PortableText /> pour du texte riche structuré au lieu d’injecter du HTML.

Props et slots

Les props sont comparables aux $args passés à get_template_part(). Ils rendent chaque entrée explicite et peuvent être vérifiés par TypeScript.

Les slots permettent à un parent de passer du markup à un composant. Un slot par défaut est utile pour le contenu de la page, tandis que les slots nommés fournissent des points d’insertion supplémentaires :

---
interface Props {
  title: string;
}

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

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

La page suivante remplit les deux slots :

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

<Card title="Dernier article">
  <p>Le contenu principal de la carte.</p>
  <a slot="footer" href="/posts/latest">Lire l'article</a>
</Card>

Les slots sont locaux à l’appel du composant. Ils ne se comportent pas comme les actions WordPress, qui peuvent recevoir des callbacks enregistrés ailleurs.

Layouts

Un layout possède la structure de document partagée qu’un thème WordPress divise souvent entre header.php et footer.php. Les pages importent le layout et passent leur contenu à travers son slot.

Le layout suivant fournit une structure de document :

---
interface Props {
  title: string;
}

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

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

La page suivante fournit le titre et le contenu principal du layout :

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

<Base title="Accueil">
  <h1>Derniers articles</h1>
</Base>

Routage basé sur les fichiers

Les fichiers dans src/pages/ définissent les routes. Les noms de fichiers entre crochets créent des segments dynamiques.

FichierURL
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

Dans src/pages/posts/[slug].astro, Astro.params.slug contient la valeur de l’URL. Lisez Routage Astro pour les paramètres rest, les redirections et les autres fonctionnalités de routage.

Rendu serveur

Les templates EmDash actuels utilisent output: "server" dans astro.config.mjs. Une page peut donc interroger la base de données à chaque requête, de sorte que le contenu publié ne dépend pas d’une nouvelle compilation statique.

N’ajoutez pas getStaticPaths() à une route de thème EmDash sauf si le site traite délibérément EmDash comme une source de données au moment de la compilation. Les thèmes fournis sont rendus côté serveur.

Lisez Rendu à la demande Astro pour le comportement au niveau du framework.

Interroger le contenu EmDash

EmDash encapsule les collections de contenu en direct d’Astro avec getEmDashCollection() et getEmDashEntry(). Les résultats de collection contiennent un tableau entries. Les résultats d’une entrée unique contiennent entry, qui est null quand aucune entrée publiée ne correspond.

L’archive suivante utilise le même tri et les mêmes identifiants que le template de blog actuel :

---
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("Impossible de charger les articles", { status: 500 });
}
---

<Base title="Articles">
  {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 est l’identifiant de route exposé par Astro et correspond normalement au slug de l’entrée. post.data.id est l’identifiant de la base de données. Utilisez data.id quand une API attend l’ID de contenu stocké, comme les fonctions d’aide pour la taxonomie ou les commentaires.

La route dynamique suivante recherche un article par le slug dans l’URL et rend son champ 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.redirect("/404");

const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("Impossible de charger l'article", { status: 500 });
if (!post) return Astro.redirect("/404");
---

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

Continuer avec Astro

Les templates EmDash utilisent aussi des styles de composants et de petits scripts navigateur, mais ce sont des fonctionnalités Astro ordinaires plutôt que des concepts EmDash. Lisez Styles et CSS pour les styles scopés et globaux, et Scripts et gestion des événements quand un composant a besoin de comportement côté navigateur.