Ce guide vous accompagne dans la création d’un blog avec EmDash, de la définition de votre type de contenu à l’affichage des articles avec catégories et étiquettes.
Prérequis
- Un site EmDash configuré et en cours d’exécution (voir Pour commencer)
- Familiarité de base avec les composants Astro
Définir la collection d’articles
EmDash crée une collection « posts » par défaut lors de la configuration. Pour la personnaliser, utilisez le panneau d’administration ou l’API.
La collection d’articles par défaut comprend :
title— Titre de l’articleslug— Identifiant adapté aux URLcontent— Corps en texte enrichiexcerpt— Description courtefeatured_image— Image d’en-tête (optionnel)status— brouillon, publié ou planifiépublishedAt— Date de publication (champ système)
Créer votre premier article
-
Ouvrez le panneau d’administration sur
/_emdash/admin -
Cliquez sur Posts dans la barre latérale
-
Cliquez sur New Post
-
Saisissez un titre et rédigez votre contenu avec l’éditeur de texte enrichi
-
Ajoutez des catégories et étiquettes dans le panneau latéral
-
Définissez le statut sur Published
-
Cliquez sur Save
Votre article est maintenant en ligne. Aucune reconstruction nécessaire.
Afficher les articles sur votre site
Lister tous les articles
Créez une page qui affiche tous les articles publiés :
---
import { getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
// Trier par date de publication, les plus récents d'abord
const sortedPosts = posts.sort(
(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0)
);
---
<Base title="Blog">
<h1>Blog</h1>
<ul>
{sortedPosts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>
<h2>{post.data.title}</h2>
<p>{post.data.excerpt}</p>
<time datetime={post.data.publishedAt?.toISOString()}>
{post.data.publishedAt?.toLocaleDateString()}
</time>
</a>
</li>
))}
</ul>
</Base>
Afficher un article individuel
Créez une route dynamique pour chaque article :
---
import { getEmDashCollection, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
import Base from "../../layouts/Base.astro";
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);
if (!post) {
return Astro.redirect("/404");
}
---
<Base title={post.data.title}>
<article>
{post.data.featured_image && (
<img src={post.data.featured_image} alt="" />
)}
<h1>{post.data.title}</h1>
<time datetime={post.data.publishedAt?.toISOString()}>
{post.data.publishedAt?.toLocaleDateString()}
</time>
<PortableText value={post.data.content} />
</article>
</Base>
Ajouter des catégories et des étiquettes
EmDash inclut des taxonomies de catégories et d’étiquettes intégrées. Consultez Taxonomies pour créer et gérer les termes.
Filtrer les articles par catégorie
---
import { getEmDashCollection, getTerm, getTaxonomyTerms } from "emdash";
import Base from "../../layouts/Base.astro";
export async function getStaticPaths() {
const categories = await getTaxonomyTerms("category");
// Aplatir les catégories hiérarchiques
const flatten = (terms) => terms.flatMap((t) => [t, ...flatten(t.children)]);
return flatten(categories).map((cat) => ({
params: { slug: cat.slug },
props: { category: cat },
}));
}
const { category } = Astro.props;
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
where: { category: category.slug },
});
---
<Base title={category.label}>
<h1>{category.label}</h1>
{category.description && <p>{category.description}</p>}
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
</Base>
Afficher les catégories sur un article
Affichez les catégories sur chaque article :
---
import { getEntryTerms } from "emdash";
interface Props {
postId: string;
}
const { postId } = Astro.props;
const categories = await getEntryTerms("posts", postId, "category");
const tags = await getEntryTerms("posts", postId, "tag");
---
<div class="post-meta">
{categories.length > 0 && (
<div class="categories">
<span>Catégories :</span>
{categories.map((cat) => (
<a href={`/category/${cat.slug}`}>{cat.label}</a>
))}
</div>
)}
{tags.length > 0 && (
<div class="tags">
<span>Étiquettes :</span>
{tags.map((tag) => (
<a href={`/tag/${tag.slug}`}>{tag.label}</a>
))}
</div>
)}
</div>
Ajouter la pagination
Pour les blogs avec de nombreux articles, ajoutez la pagination :
---
import { getEmDashCollection } from "emdash";
import Base from "../../../layouts/Base.astro";
const POSTS_PER_PAGE = 10;
export async function getStaticPaths() {
const { entries: allPosts } = await getEmDashCollection("posts", {
status: "published",
});
const totalPages = Math.ceil(allPosts.length / POSTS_PER_PAGE);
return Array.from({ length: totalPages }, (_, i) => ({
params: { page: String(i + 1) },
props: { currentPage: i + 1, totalPages },
}));
}
const { currentPage, totalPages } = Astro.props;
const { entries: allPosts } = await getEmDashCollection("posts", {
status: "published",
});
const sortedPosts = allPosts.sort(
(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0)
);
const start = (currentPage - 1) * POSTS_PER_PAGE;
const posts = sortedPosts.slice(start, start + POSTS_PER_PAGE);
---
<Base title={`Blog - Page ${currentPage}`}>
<h1>Blog</h1>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
<nav>
{currentPage > 1 && (
<a href={`/blog/page/${currentPage - 1}`}>Précédent</a>
)}
<span>Page {currentPage} sur {totalPages}</span>
{currentPage < totalPages && (
<a href={`/blog/page/${currentPage + 1}`}>Suivant</a>
)}
</nav>
</Base>
Ajouter un flux RSS
Créez un flux RSS pour votre blog :
import rss from "@astrojs/rss";
import { getEmDashCollection } from "emdash";
export async function GET(context) {
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
});
return rss({
title: "My Blog",
description: "A blog built with EmDash",
site: context.site,
items: posts.map((post) => ({
title: post.data.title,
pubDate: post.data.publishedAt,
description: post.data.excerpt,
link: `/blog/${post.data.slug}`,
})),
});
}
Installez le paquet RSS si ce n’est pas déjà fait :
npm install @astrojs/rss
Prochaines étapes
- Travailler avec le contenu — Opérations CRUD dans l’admin
- Médiathèque — Ajouter des images à vos articles
- Taxonomies — Créer des systèmes de classification personnalisés