Taxonomies

Sur cette page

Une taxonomie est une classification nommée appliquée à une ou plusieurs collections. EmDash démarre avec la taxonomie hiérarchique category et la taxonomie plate tag pour les posts. Un site peut aussi définir des taxonomies telles que genre, topic ou difficulty.

Les termes appartiennent à une taxonomie. Une catégorie telle que « Guides » peut avoir des catégories enfants, tandis que les tags et les autres taxonomies plates ont un niveau.

Gérer les termes

Ouvrez une taxonomie depuis Taxonomies dans l’administration EmDash.

  1. Cliquez sur Add Category, Add Tag ou l’action équivalente pour la taxonomie actuelle.

  2. Saisissez le libellé et le slug. Pour une taxonomie hiérarchique, choisissez un parent lorsque le terme appartient sous un autre terme.

  3. Ajoutez une description facultative, puis créez le terme.

  4. Utilisez les contrôles de déplacement dans la liste des termes pour définir l’ordre dans le groupe parent actuel.

Les éditeurs assignent les termes depuis les panneaux de taxonomie dans une entrée de contenu. La définition de la taxonomie contrôle quelles collections affichent chaque panneau.

Supprimer un terme retire ses assignations du contenu. Cela ne supprime pas les entrées de contenu.

Ajouter un tag à plusieurs posts

Les éditeurs peuvent sélectionner des posts dans une liste de collection et cliquer sur Add tag, ou ouvrir Tags et cliquer sur Add to posts pour coller des URL publiques de posts (une par ligne, jusqu’à 50). Choisissez un tag existant ou créez-en un dans la boîte de dialogue, puis cliquez sur Review posts. Vérifiez chaque titre et langue correspondants, puis cliquez sur le bouton indiquant combien de posts seront tagués. Les liens qui ne correspondent pas exactement à un post publié sur ce site sont signalés plutôt que devinés.

L’ajout du tag prend effet immédiatement, même lorsqu’un post a d’autres modifications de brouillon non publiées ; cela ne publie pas ces modifications. Les tags existants restent en place, et les posts qui ont déjà le tag sont ignorés. La liste de résultats montre quels posts ont été tagués, ignorés ou n’ont pas pu l’être ; utilisez Retry failures pour les échecs d’écriture. La correspondance d’URL utilise l’origine publique configurée du site et les motifs d’URL des collections, y compris les chemins de date et de langue.

Ajouter une taxonomie personnalisée

Créez une taxonomie lorsqu’une collection existante a besoin d’une classification séparée.

  1. Ouvrez Taxonomies et cliquez sur New Taxonomy.

  2. Saisissez un libellé et un nom stable. Les noms commencent par une lettre minuscule et ne contiennent que des lettres minuscules, des chiffres et des underscores.

  3. Activez Hierarchical si les termes ont besoin de relations parent et enfant.

  4. Sélectionnez chaque collection qui peut utiliser la taxonomie, puis cliquez sur Create Taxonomy.

  5. Ajoutez les termes initiaux et assignez-les au contenu.

Les modèles interrogent le nom stable. Modifier un libellé d’affichage ne nécessite pas de changement de modèle.

Les taxonomies personnalisées utilisent les mêmes helpers de requête et de filtre que les catégories et les tags. L’exemple suivant lit les termes genre et filtre les livres par l’un de leurs slugs :

import { getEmDashCollection, getTaxonomyTerms } from "emdash";

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

Supprimer une taxonomie

Ouvrez la taxonomie dans l’administration, puis choisissez Delete taxonomy dans le menu d’actions de l’en-tête de page et confirmez. L’action nécessite la permission taxonomies:manage, que détiennent les éditeurs et les administrateurs.

Supprimer une taxonomie supprime ses termes dans chaque langue et retire ces termes du contenu classé sous eux. Les entrées de contenu elles-mêmes sont conservées.

Interroger une liste de termes

Utilisez getTaxonomyTerms() pour rendre un index de taxonomie, une liste de navigation ou un ensemble de filtres. Les taxonomies hiérarchiques renvoient un arbre via le tableau children de chaque terme.

Les comptes de termes sont inclus par défaut et nécessitent une agrégation sur les collections assignées de la taxonomie. Ignorez ce travail lorsque le composant n’affiche pas les comptes.

Le composant suivant rend des liens de catégorie sans comptes :

---
import { getTaxonomyTerms } from "emdash";
import { getRelativeLocaleUrl } from "astro:i18n";

const locale = Astro.currentLocale;
const categories = await getTaxonomyTerms("category", {
  locale,
  includeCounts: false,
});

function categoryHref(slug: string) {
  const path = `/category/${slug}`;
  return locale ? getRelativeLocaleUrl(locale, path) : path;
}
---

<nav aria-label="Categories">
  <ul>
    {categories.map((category) => (
      <li>
        <a href={categoryHref(category.slug)}>{category.label}</a>
        {category.children.length > 0 && (
          <ul>
            {category.children.map((child) => (
              <li><a href={categoryHref(child.slug)}>{child.label}</a></li>
            ))}
          </ul>
        )}
      </li>
    ))}
  </ul>
</nav>

Lorsqu’un composant affiche l’usage, omettez includeCounts: false et rendez term.count. Le compte inclut les entrées visibles publiquement dans la locale utilisée pour la requête.

Construire une archive de taxonomie

Décodez un paramètre de route dynamique avant de rechercher un terme. Interrogez le terme et le contenu avec la même locale, et passez les chemins générés par le helper d’URL de locale d’Astro.

La route suivante liste les posts publiés dans une catégorie :

---
import { decodeSlug, getEmDashCollection, getTerm } from "emdash";
import { getRelativeLocaleUrl } from "astro:i18n";
import Base from "../../layouts/Base.astro";

const locale = Astro.currentLocale;
const slug = decodeSlug(Astro.params.slug);
const category = slug
  ? await getTerm("category", slug, { locale, includeCounts: false })
  : null;

if (!category) {
  return Astro.redirect("/404");
}

const { entries: posts } = await getEmDashCollection("posts", {
  status: "published",
  locale,
  where: { category: category.slug },
  orderBy: { published_at: "desc" },
});

function postHref(postSlug: string) {
  const path = `/posts/${postSlug}`;
  return locale ? getRelativeLocaleUrl(locale, path) : path;
}
---

<Base title={`${category.label} posts`}>
  <h1>{category.label}</h1>
  {category.description && <p>{category.description}</p>}

  {posts.length > 0 ? (
    <ul>
      {posts.map((post) => (
        post.data.slug && (
          <li>
            <a href={postHref(post.data.slug)}>{post.data.title}</a>
          </li>
        )
      ))}
    </ul>
  ) : (
    <p>No posts in this category.</p>
  )}
</Base>

where utilise le nom de la taxonomie comme clé et un slug de terme comme valeur. Les identifiants de tri de requête utilisent des noms de champs de base tels que published_at ; les données d’entrée exposent la valeur correspondante comme publishedAt.

Utilisez la route publique réelle de la collection dans postHref(). Si la collection utilise un urlPattern personnalisé, construisez les liens à partir de ce motif plutôt que d’assumer /posts/{slug}.

Afficher les termes d’une entrée

getEmDashEntry() et getEmDashCollection() hydratent les termes assignés sur entry.data.terms. Lisez cette valeur au lieu d’exécuter une requête getEntryTerms() pour chaque entrée d’une liste.

Le composant suivant rend les catégories et tags déjà chargés avec un post :

---
import type { ContentEntry, InferCollectionData } from "emdash";
import { getRelativeLocaleUrl } from "astro:i18n";

interface Props {
  post: ContentEntry<InferCollectionData<"posts">>;
}

const { post } = Astro.props;
const locale = Astro.currentLocale;
const categories = post.data.terms?.category ?? [];
const tags = post.data.terms?.tag ?? [];

function termHref(taxonomy: string, slug: string) {
  const path = `/${taxonomy}/${slug}`;
  return locale ? getRelativeLocaleUrl(locale, path) : path;
}
---

{categories.length > 0 && (
  <ul aria-label="Categories">
    {categories.map((category) => (
      <li>
        <a href={termHref("category", category.slug)}>{category.label}</a>
      </li>
    ))}
  </ul>
)}

{tags.length > 0 && (
  <ul aria-label="Tags">
    {tags.map((tag) => (
      <li>
        <a href={termHref("tag", tag.slug)}>{tag.label}</a>
      </li>
    ))}
  </ul>
)}

Utilisez getEntryTerms() lorsque vous n’avez qu’un nom de collection et un ID d’entrée. Utilisez getTermsForEntries() pour regrouper les termes de plusieurs entrées lorsqu’ils n’ont pas été hydratés par la requête de contenu.

Traduire les taxonomies et les termes

Les définitions de taxonomie et les termes ont une ligne par locale. EmDash enregistre quelles lignes sont des traductions de la même taxonomie ou du même terme. Les assignations de contenu utilisent cette identité partagée, de sorte qu’une assignation faite dans une locale se résout au terme traduit dans une autre locale lorsqu’il en existe un.

Une définition de taxonomie répartit ses champs entre la taxonomie et chaque locale :

ChampAppartient àEffet
nameTaxonomieFixe après la création. La définition de chaque locale utilise le même nom.
hierarchical, collectionsTaxonomieIdentique dans chaque locale. Modifier l’un ou l’autre via n’importe quelle locale le change pour toutes les locales.
label, labelSingularLocaleChaque définition de locale a les siens.

Une définition créée pour un nom qui existe déjà dans une autre locale rejoint cette taxonomie, avec ou sans translationOf, et prend ses hierarchical et collections. La créer avec des valeurs différentes échoue ; changez-les avec une mise à jour. Une locale sans sa propre définition liste toujours les termes de la taxonomie et affiche le libellé de la première locale de sa chaîne de repli qui en a un, sinon le libellé de la locale par défaut, sinon le libellé de la locale au code de locale le plus bas.

Utilisez le sélecteur de locale sur une page de taxonomie pour gérer les termes dans chaque locale configurée. Ouvrez la boîte de dialogue d’édition d’un terme et utilisez son panneau Translations pour ajouter ou ouvrir une autre locale. Un terme traduit peut utiliser un slug et un libellé différents.

Le parent et la position d’un terme sont partagés par chaque locale. Une traduction créée sans parent prend le parent et la position de son terme. Créer une traduction sous un parent différent, ou changer le parent via n’importe quelle locale, déplace le terme dans chaque locale.

Les helpers de requête utilisent une locale explicite lorsqu’elle est fournie. Sinon ils utilisent la locale de la requête actuelle, puis la locale par défaut configurée. Les recherches de terme unique suivent la chaîne de repli configurée lorsque la traduction demandée est absente.

Voir Internationalization pour le routage de locale et la configuration de repli et Working with Content pour l’édition des entrées. La référence d’API runtime documente les helpers de requête de taxonomie. Pour des changements programmatiques, authentifiez-vous avec un jeton Bearer et ajoutez X-EmDash-Request: 1 à chaque requête qui change l’état. Voir les endpoints de taxonomie pour les corps de requête et les réponses.