Créer un blog

Sur cette page

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’article
  • slug — Identifiant adapté aux URL
  • content — Corps en texte enrichi
  • excerpt — Description courte
  • featured_image — Image d’en-tête (optionnel)
  • status — brouillon, publié ou planifié
  • publishedAt — Date de publication (champ système)

Créer votre premier article

  1. Ouvrez le panneau d’administration sur /_emdash/admin

  2. Cliquez sur Posts dans la barre latérale

    Liste des articles EmDash affichant les titres, le statut et les dates
  3. Cliquez sur New Post

    Éditeur d'articles EmDash avec titre, contenu et options de publication
  4. Saisissez un titre et rédigez votre contenu avec l’éditeur de texte enrichi

  5. Ajoutez des catégories et étiquettes dans le panneau latéral

  6. Définissez le statut sur Published

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