Interroger le contenu

Sur cette page

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 :

FonctionObjectifRetourne
getEmDashCollectionRécupérer toutes les entrées d’un type de contenu{ entries, error }
getEmDashEntryRé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