EmDash fournit des fonctions de requête pour récupérer le contenu dans vos pages et composants Astro. Ces fonctions suivent le modèle des collections de contenu en direct d’Astro, renvoyant des résultats structurés avec gestion des erreurs.
Fonctions de requête
EmDash exporte deux fonctions de requête principales :
| Fonction | Objectif | Retourne |
|---|---|---|
getEmDashCollection | Récupérer toutes les entrées d’un type de contenu | { entries, error } |
getEmDashEntry | Récupérer une seule entrée par ID ou slug | { entry, error, isPreview } |
Importez-les depuis emdash :
import { getEmDashCollection, getEmDashEntry } from "emdash";
Obtenir toutes les entrées
Utilisez getEmDashCollection pour récupérer toutes les entrées d’un type de contenu :
---
import { getEmDashCollection } from "emdash";
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) {
console.error("Échec du chargement des articles :", error);
}
---
<ul>
{posts.map((post) => (
<li>{post.data.title}</li>
))}
</ul>
Filtrer par locale
Lorsque l’i18n est activé, filtrez par locale pour récupérer le contenu dans une langue spécifique :
// Articles en français
const { entries: frenchPosts } = await getEmDashCollection("posts", {
locale: "fr",
status: "published",
});
// Utiliser la locale de la requête actuelle
const { entries: localizedPosts } = await getEmDashCollection("posts", {
locale: Astro.currentLocale,
status: "published",
});
Pour les entrées individuelles, passez locale comme troisième argument :
const { entry: post } = await getEmDashEntry("posts", "my-post", {
locale: Astro.currentLocale,
});
Lorsque locale est omis, il prend par défaut la locale actuelle de la requête. Si aucune traduction n’existe pour la locale demandée, la chaîne de repli est suivie.
Filtrer par statut
Récupérer uniquement le contenu publié ou brouillon :
// Uniquement les articles publiés
const { entries: published } = await getEmDashCollection("posts", {
status: "published",
});
// Uniquement les brouillons
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});
Limiter les résultats
Restreindre le nombre d’entrées retournées :
// Obtenir les 5 articles les plus récents
const { entries: recentPosts } = await getEmDashCollection("posts", {
status: "published",
limit: 5,
});
Filtrer par taxonomie
Filtrer les entrées par catégorie, tag ou termes de taxonomie personnalisés :
// Articles dans la catégorie "news"
const { entries: newsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { category: "news" },
});
// Articles avec le tag "javascript"
const { entries: jsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: "javascript" },
});
// Articles correspondant à l'un de plusieurs termes
const { entries: featuredNews } = await getEmDashCollection("posts", {
status: "published",
where: { category: ["news", "featured"] },
});
Le filtre where utilise une logique OU lorsque plusieurs valeurs sont fournies pour une seule taxonomie.
Gestion des erreurs
Vérifiez toujours les erreurs lorsque la fiabilité est importante :
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) {
// Enregistrer et gérer avec élégance
console.error("Échec du chargement des articles :", error);
return new Response("Erreur serveur", { status: 500 });
}
Obtenir une seule entrée
Utilisez getEmDashEntry pour récupérer une entrée par son ID ou son slug :
---
import { getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Erreur serveur", { status: 500 });
}
if (!post) {
return Astro.redirect("/404");
}
---
<article>
<h1>{post.data.title}</h1>
<PortableText value={post.data.content} />
</article>
Type de retour d’entrée
getEmDashEntry retourne un objet résultat :
interface EntryResult<T> {
entry: ContentEntry<T> | null; // null si non trouvé
error?: Error; // Défini uniquement pour les erreurs réelles (pas "non trouvé")
isPreview: boolean; // true si affichage d'aperçu/contenu brouillon
}
interface ContentEntry<T> {
id: string;
data: T;
edit: EditProxy; // Annotations d'édition visuelle
}
L’objet data dans entry contient tous les champs définis pour le type de contenu. Le proxy edit fournit des annotations d’édition visuelle (voir ci-dessous).
Mode aperçu
EmDash gère l’aperçu automatiquement via middleware. Lorsqu’une URL contient un token _preview valide, le middleware le vérifie et configure le contexte de la requête. Vos fonctions de requête servent alors le contenu brouillon sans paramètres spéciaux :
---
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
// Pas besoin de gestion spéciale d'aperçu — le middleware le fait automatiquement
const { entry, isPreview, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Erreur serveur", { status: 500 });
}
if (!entry) {
return Astro.redirect("/404");
}
---
{isPreview && (
<div class="preview-banner">
Affichage de l'aperçu. Ce contenu n'est pas publié.
</div>
)}
<article>
<h1>{entry.data.title}</h1>
<PortableText value={entry.data.content} />
</article>
Édition visuelle
Chaque entrée retournée par les fonctions de requête inclut un proxy edit pour annoter vos templates. Étalez-le sur les éléments pour activer l’édition en ligne pour les éditeurs authentifiés :
<article {...entry.edit}>
<h1 {...entry.edit.title}>{entry.data.title}</h1>
<div {...entry.edit.content}>
<PortableText value={entry.data.content} />
</div>
</article>
En mode édition, {...entry.edit.title} produit un attribut data-emdash-ref que la barre d’outils d’édition visuelle utilise pour activer l’édition en ligne. En production, les étalements du proxy ne produisent aucune sortie.
Trier les résultats
getEmDashCollection ne garantit pas l’ordre de tri. Triez les résultats dans votre template :
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
// Trier par date de publication, le plus récent en premier
const sorted = posts.sort(
(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),
);
Modèles de tri courants
// Alphabétique par titre
posts.sort((a, b) => a.data.title.localeCompare(b.data.title));
// Par champ d'ordre personnalisé
posts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// Ordre aléatoire
posts.sort(() => Math.random() - 0.5);
Types TypeScript
Générez des types TypeScript pour vos collections :
npx emdash types
Cela crée .emdash/types.ts avec des interfaces pour chaque collection. Utilisez-les pour la sécurité des types :
import { getEmDashCollection, getEmDashEntry } from "emdash";
import type { Post } from "../.emdash/types";
// Requête de collection avec sécurité des types
const { entries: posts } = await getEmDashCollection<Post>("posts");
// posts est ContentEntry<Post>[]
// Requête d'entrée avec sécurité des types
const { entry: post } = await getEmDashEntry<Post>("posts", "my-post");
// post est ContentEntry<Post> | null
Rendu statique vs. serveur
Le contenu EmDash fonctionne avec les pages statiques et rendues côté serveur.
Statique (Pré-rendu)
Pour les pages statiques, utilisez getStaticPaths pour générer des routes au moment de la compilation :
---
import { getEmDashCollection, getEmDashEntry } from "emdash";
export async function getStaticPaths() {
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
return posts.map((post) => ({
params: { slug: post.data.slug },
}));
}
const { slug } = Astro.params;
const { entry: post } = await getEmDashEntry("posts", slug);
---
Rendu serveur
Pour les pages rendues côté serveur, interrogez le contenu directement :
---
export const prerender = false;
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) {
return new Response("Erreur serveur", { status: 500 });
}
if (!post) {
return new Response(null, { status: 404 });
}
---
Considérations de performance
Mise en cache
EmDash utilise les collections de contenu en direct d’Astro, qui gèrent automatiquement la mise en cache. Pour les pages rendues côté serveur, envisagez d’ajouter des en-têtes de cache HTTP :
---
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
// Mettre en cache pendant 5 minutes
Astro.response.headers.set("Cache-Control", "public, max-age=300");
---
Éviter les requêtes redondantes
Interrogez une fois et passez les données aux composants :
---
import { getEmDashCollection } from "emdash";
import PostList from "../components/PostList.astro";
import Sidebar from "../components/Sidebar.astro";
// Interroger une fois
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
const featured = posts.filter((p) => p.data.featured);
const recent = posts.slice(0, 5);
---
<PostList posts={featured} />
<Sidebar posts={recent} />
Prochaines étapes
- Créer un blog - Construire un blog complet
- Taxonomies - Filtrer par catégories et tags
- Travailler avec le contenu - Opérations CRUD d’administration
- Internationalisation - Contenu multilingue et traductions