Aller au contenu

Taxonomies

Les taxonomies sont des systèmes de classification pour organiser le contenu. EmDash inclut des catégories et des étiquettes intégrées, et prend en charge les taxonomies personnalisées pour des besoins de classification spécialisés.

EmDash fournit deux taxonomies par défaut :

TaxonomieTypeDescription
CatégoriesHiérarchiqueClassification imbriquée avec des relations parent-enfant
ÉtiquettesPlateLibellés simples sans hiérarchie

Les deux sont disponibles pour la collection d’articles par défaut.

  1. Allez sur la page de la taxonomie (par exemple, /_emdash/admin/taxonomies/category)

  2. Saisissez le nom du terme dans le formulaire Ajouter

  3. Optionnellement, définissez :

    • Slug - Identifiant d’URL (généré automatiquement à partir du nom)
    • Parent - Pour les taxonomies hiérarchiques
    • Description - Description du terme
  4. Cliquez sur Ajouter

  1. Allez sur la page des termes de la taxonomie

  2. Cliquez sur Modifier à côté du terme

  3. Mettez à jour le nom, le slug, le parent ou la description

  4. Cliquez sur Enregistrer

  1. Allez sur la page des termes de la taxonomie

  2. Cliquez sur Supprimer à côté du terme

  3. Confirmez la suppression

EmDash fournit des fonctions pour interroger les termes de taxonomie et filtrer le contenu par terme.

Récupérer tous les termes d’une taxonomie :

import { getTaxonomyTerms } from "emdash";
// Obtenir toutes les catégories (retourne une structure arborescente)
const categories = await getTaxonomyTerms("category");
// Obtenir toutes les étiquettes (retourne une liste plate)
const tags = await getTaxonomyTerms("tag");

Pour les taxonomies hiérarchiques, les termes incluent un tableau children :

interface TaxonomyTerm {
id: string;
name: string; // Taxonomy name ("category")
slug: string; // Term slug ("news")
label: string; // Display label ("News")
parentId?: string;
description?: string;
children: TaxonomyTerm[];
count?: number; // Number of entries with this term
}
import { getTerm } from "emdash";
const category = await getTerm("category", "news");
// Retourne TaxonomyTerm ou null
import { getEntryTerms } from "emdash";
// Obtenir toutes les catégories pour un article
const categories = await getEntryTerms("posts", "post-123", "category");
// Obtenir toutes les étiquettes pour un article
const tags = await getEntryTerms("posts", "post-123", "tag");

Utilisez getEmDashCollection avec le filtre where :

import { getEmDashCollection } from "emdash";
// Articles dans la catégorie "news"
const { entries: newsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { category: "news" },
});
// Articles avec l'étiquette "javascript"
const { entries: jsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: "javascript" },
});

Ou utilisez la fonction de commodité :

import { getEntriesByTerm } from "emdash";
const newsPosts = await getEntriesByTerm("posts", "category", "news");

Créez une page qui liste les articles d’une catégorie :

astro title="src/pages/category/[slug].astro"
---
import { getTaxonomyTerms, getTerm, getEmDashCollection } from "emdash";
import Base from "../../../layouts/Base.astro";
export async function getStaticPaths() {
const categories = await getTaxonomyTerms("category");
// Aplatir l'arbre hiérarchique pour le routage
function flatten(terms) {
return terms.flatMap((term) => [term, ...flatten(term.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>
}
<p>{category.count} articles</p>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
</Base>

Créez une page qui liste les articles avec une étiquette :

astro title="src/pages/tag/[slug].astro"
---
import { getTaxonomyTerms, getEmDashCollection } from "emdash";
import Base from "../../../layouts/Base.astro";
export async function getStaticPaths() {
const tags = await getTaxonomyTerms("tag");
return tags.map((tag) => ({
params: { slug: tag.slug },
props: { tag },
}));
}
const { tag } = Astro.props;
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: tag.slug },
});
---
<Base title={`Articles étiquetés "${tag.label}"`}>
<h1>#{tag.label}</h1>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
</Base>

Affichez une liste de catégories avec le nombre d’articles :

astro title="src/components/CategoryList.astro"
---
import { getTaxonomyTerms } from "emdash";
const categories = await getTaxonomyTerms("category");
---
<nav class="category-list">
<h3>Catégories</h3>
<ul>
{categories.map((cat) => (
<li>
<a href={`/category/${cat.slug}`}>
{cat.label} ({cat.count})
</a>
{cat.children.length > 0 && (
<ul>
{cat.children.map((child) => (
<li>
<a href={`/category/${child.slug}`}>
{child.label} ({child.count})
</a>
</li>
))}
</ul>
)}
</li>
))}
</ul>
</nav>

Affichez les étiquettes avec une taille basée sur l’utilisation :

astro title="src/components/TagCloud.astro"
---
import { getTaxonomyTerms } from "emdash";
const tags = await getTaxonomyTerms("tag");
// Calculer les tailles de police basées sur le nombre
const counts = tags.map((t) => t.count ?? 0);
const maxCount = Math.max(...counts, 1);
const minSize = 0.8;
const maxSize = 2;
function getSize(count: number) {
const ratio = count / maxCount;
return minSize + ratio * (maxSize - minSize);
}
---
<div class="tag-cloud">
{tags.map((tag) => (
<a
href={`/tag/${tag.slug}`}
style={`font-size: ${getSize(tag.count ?? 0)}rem`}
>
{tag.label}
</a>
))}
</div>

Affichez les catégories et étiquettes sur un article :

astro title="src/components/PostTerms.astro"
---
import { getEntryTerms } from "emdash";
interface Props {
collection: string;
entryId: string;
}
const { collection, entryId } = Astro.props;
const categories = await getEntryTerms(collection, entryId, "category");
const tags = await getEntryTerms(collection, entryId, "tag");
---
<div class="post-terms">
{categories.length > 0 && (
<div class="categories">
<span>Publié dans :</span>
{categories.map((cat, i) => (
<>
{i > 0 && ", "}
<a href={`/category/${cat.slug}`}>{cat.label}</a>
</>
))}
</div>
)}
{tags.length > 0 && (
<div class="tags">
{tags.map((tag) => (
<a href={`/tag/${tag.slug}`} class="tag">
#{tag.label}
</a>
))}
</div>
)}
</div>

Créez des taxonomies au-delà des catégories et des étiquettes pour des besoins spécialisés.

Utilisez l’API d’administration pour créer une taxonomie :

Fenêtre de terminal
POST /_emdash/api/taxonomies
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN
{
"name": "genre",
"label": "Genres",
"labelSingular": "Genre",
"hierarchical": true,
"collections": ["books", "movies"]
}

Interrogez et affichez les taxonomies personnalisées de la même manière que celles intégrées :

import { getTaxonomyTerms, getEmDashCollection } from "emdash";
// Obtenir tous les genres
const genres = await getTaxonomyTerms("genre");
// Obtenir les livres d'un genre
const { entries: sciFiBooks } = await getEmDashCollection("books", {
where: { genre: "science-fiction" },
});

Les taxonomies spécifient à quelles collections elles s’appliquent :

{
"name": "difficulty",
"label": "Difficulty Levels",
"hierarchical": false,
"collections": ["recipes", "tutorials"]
}
Point de TerminaisonMéthodeDescription
/_emdash/api/taxonomiesGETLister les définitions de taxonomies
/_emdash/api/taxonomiesPOSTCréer une taxonomie
/_emdash/api/taxonomies/:name/termsGETLister les termes
/_emdash/api/taxonomies/:name/termsPOSTCréer un terme
/_emdash/api/taxonomies/:name/terms/:slugGETObtenir un terme
/_emdash/api/taxonomies/:name/terms/:slugPUTMettre à jour un terme
/_emdash/api/taxonomies/:name/terms/:slugDELETESupprimer un terme
Fenêtre de terminal
POST /_emdash/api/content/posts/post-123/terms/category
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN
{
"termIds": ["term_news", "term_featured"]
}