Taxonomies

Sur cette page

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

Taxonomies intégrées

TaxonomieTypeDescription
CatégoriesHiérarchiqueClassification imbriquée avec relations parent-enfant
TagsPlatLabels simples sans hiérarchie

Les deux sont disponibles pour la collection de posts par défaut.

Gérer les termes

Créer un terme

Tableau de bord admin

  1. Allez à la page de taxonomie (ex : /_emdash/admin/taxonomies/category)
  2. Entrez le nom du terme dans le formulaire Ajouter nouveau
  3. Définissez optionnellement :
    • Slug - Identifiant URL (généré automatiquement à partir du nom)
    • Parent - Pour les taxonomies hiérarchiques
    • Description - Description du terme
  4. Cliquez sur Ajouter

Éditeur de contenu

  1. Ouvrez une entrée de contenu dans l’éditeur
  2. Trouvez le panneau de taxonomie dans la barre latérale
  3. Pour les catégories, cochez les cases pour les termes applicables, ou cliquez sur + Ajouter nouveau
  4. Pour les tags, tapez les noms de tags séparés par des virgules
  5. Enregistrez le contenu

API

POST /_emdash/api/taxonomies/category/terms
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
  "slug": "tutorials",
  "label": "Tutoriels",
  "parentId": "term_abc",
  "description": "Guides pratiques et tutoriels"
}

Modifier un terme

  1. Allez à la page des termes de taxonomie
  2. Cliquez sur Modifier à côté du terme
  3. Mettez à jour le nom, slug, parent ou description
  4. Cliquez sur Enregistrer

Supprimer un terme

  1. Allez à la page des termes de taxonomie
  2. Cliquez sur Supprimer à côté du terme
  3. Confirmez la suppression

Requêter les taxonomies

Obtenir tous les termes

import { getTaxonomyTerms } from "emdash";

const categories = await getTaxonomyTerms("category");
const tags = await getTaxonomyTerms("tag");
interface TaxonomyTerm {
	id: string;
	name: string;
	slug: string;
	label: string;
	parentId?: string;
	description?: string;
	children: TaxonomyTerm[];
	count?: number;
}

Si vous n’avez besoin que des labels et slugs, ignorez le calcul du comptage :

const tags = await getTaxonomyTerms("tag", { includeCounts: false });

Obtenir un seul terme

import { getTerm } from "emdash";
const category = await getTerm("category", "news");
const category = await getTerm("category", "news", { includeCounts: false });

Obtenir les termes d’une entrée

import { getEntryTerms } from "emdash";
const categories = await getEntryTerms("posts", "post-123", "category");
const tags = await getEntryTerms("posts", "post-123", "tag");

Filtrer le contenu par terme

import { getEmDashCollection } from "emdash";

const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});
import { getEntriesByTerm } from "emdash";
const newsPosts = await getEntriesByTerm("posts", "category", "news");

Construire des pages de taxonomie

Archive de catégories

---
import { getTaxonomyTerms, getTerm, getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";

export async function getStaticPaths() {
  const categories = await getTaxonomyTerms("category");
  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>

Archive de tags

---
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 tagué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>

Widget liste de catégories

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

Nuage de tags

---
import { getTaxonomyTerms } from "emdash";
const tags = await getTaxonomyTerms("tag");
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>

Afficher les termes sur le contenu

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

Taxonomies personnalisées

POST /_emdash/api/taxonomies
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
  "name": "genre",
  "label": "Genres",
  "labelSingular": "Genre",
  "hierarchical": true,
  "collections": ["books", "movies"]
}
import { getTaxonomyTerms, getEmDashCollection } from "emdash";

const genres = await getTaxonomyTerms("genre");
const { entries: sciFiBooks } = await getEmDashCollection("books", {
	where: { genre: "science-fiction" },
});

Référence API taxonomie

EndpointMéthodeDescription
/_emdash/api/taxonomiesGETLister les définitions
/_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
POST /_emdash/api/content/posts/post-123/terms/category
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
  "termIds": ["term_news", "term_featured"]
}

Prochaines étapes