Taxonomias

Nesta página

Uma taxonomia é uma classificação nomeada aplicada a uma ou mais collections. O EmDash começa com a taxonomia hierárquica category e a taxonomia plana tag para posts. Um site também pode definir taxonomias como genre, topic ou difficulty.

Os termos pertencem a uma taxonomia. Uma categoria como “Guides” pode ter categorias filhas, enquanto tags e outras taxonomias planas têm um nível.

Gerenciar termos

Abra uma taxonomia em Taxonomies no admin do EmDash.

  1. Clique em Add Category, Add Tag ou na ação equivalente da taxonomia atual.

  2. Informe o rótulo e o slug. Em uma taxonomia hierárquica, escolha um pai quando o termo ficar abaixo de outro termo.

  3. Adicione uma descrição opcional e depois crie o termo.

  4. Use os controles de movimentação na lista de termos para definir a ordem dentro do grupo do pai atual.

Os editores atribuem termos nos painéis de taxonomia de uma entrada de conteúdo. A definição da taxonomia controla em quais collections cada painel é exibido.

Excluir um termo remove suas atribuições do conteúdo. Isso não exclui as entradas de conteúdo.

Adicionar um termo a vários posts

Os editores podem selecionar posts em uma lista de collection e clicar em Add seguido do nome singular da taxonomia (por exemplo, Add tag), ou abrir a página de uma taxonomia e clicar em Add to posts para colar URLs públicas de posts (uma por linha, até 50). Quando mais de uma taxonomia se aplica à collection, a lista mostra Add term e a caixa de diálogo pergunta qual taxonomia usar. Escolha um termo existente ou crie um na caixa de diálogo e depois clique em Review posts. Confira cada título e idioma correspondente e depois clique no botão que mostra quantos posts serão atualizados. Links que não correspondem exatamente a um post publicado neste site são sinalizados em vez de adivinhados. Somente entradas de collections que usam a taxonomia escolhida podem ser correspondidas.

Adicionar o termo tem efeito imediato, mesmo quando um post tem outras edições de rascunho não publicadas; isso não publica essas edições. Os termos existentes permanecem e os posts que já têm o termo são ignorados. A lista de resultados mostra quais posts foram atualizados, ignorados ou não puderam ser atualizados; use Retry failures para falhas de gravação. A correspondência de URLs usa a origem pública configurada do site e os padrões de URL das collections, incluindo caminhos de data e de idioma.

Adicionar uma taxonomia personalizada

Crie uma taxonomia quando uma collection existente precisar de uma classificação separada.

  1. Abra Taxonomies e clique em New Taxonomy.

  2. Informe um rótulo e um nome estável. Os nomes começam com uma letra minúscula e contêm apenas letras minúsculas, números e sublinhados.

  3. Ative Hierarchical se os termos precisarem de relações de pai e filho.

  4. Selecione cada collection que pode usar a taxonomia e depois clique em Create Taxonomy.

  5. Adicione os termos iniciais e atribua-os ao conteúdo.

Os templates consultam o nome estável. Alterar um rótulo de exibição não exige mudar o template.

As taxonomias personalizadas usam os mesmos helpers de consulta e filtro que as categorias e as tags. O exemplo a seguir lê os termos de genre e filtra livros por um de seus slugs:

import { getEmDashCollection, getTaxonomyTerms } from "emdash";

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

Excluir uma taxonomia

Abra a taxonomia no admin, escolha Delete taxonomy no menu de ações do cabeçalho da página e confirme. A ação exige a permissão taxonomies:manage, que editores e administradores possuem.

Excluir uma taxonomia exclui seus termos em todos os idiomas e remove esses termos do conteúdo classificado sob eles. As entradas de conteúdo em si são mantidas.

Consultar uma lista de termos

Use getTaxonomyTerms() para renderizar um índice de taxonomia, uma lista de navegação ou um conjunto de filtros. As taxonomias hierárquicas retornam uma árvore por meio do array children de cada termo.

As contagens de termos são incluídas por padrão e exigem uma agregação nas collections atribuídas à taxonomia. Pule esse trabalho quando o componente não exibir contagens.

O componente a seguir renderiza links de categorias sem contagens:

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

Quando um componente exibir o uso, omita includeCounts: false e renderize term.count. A contagem inclui as entradas publicamente visíveis no locale usado na consulta.

Construir um arquivo de taxonomia

Decodifique o parâmetro de uma rota dinâmica antes de buscar um termo. Consulte o termo e o conteúdo com o mesmo locale e passe os caminhos gerados pelo helper de URL de locale do Astro.

A rota a seguir lista os posts publicados em uma categoria:

---
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.rewrite("/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 usa o nome da taxonomia como chave e o slug de um termo como valor. Os identificadores de ordenação das consultas usam nomes de campo do banco de dados, como published_at; os dados da entrada expõem o valor correspondente como publishedAt.

Use a rota pública real da collection em postHref(). Se a collection usar um urlPattern personalizado, construa os links a partir desse padrão em vez de presumir /posts/{slug}.

Exibir os termos de uma entrada

getEmDashEntry() e getEmDashCollection() hidratam os termos atribuídos em entry.data.terms. Leia esse valor em vez de executar uma consulta getEntryTerms() para cada entrada de uma lista.

O componente a seguir renderiza as categorias e tags já carregadas com um 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>
)}

Use getEntryTerms() quando tudo o que você tem é o nome de uma collection e o ID de uma entrada. Use getTermsForEntries() para obter em lote os termos de várias entradas quando eles não foram hidratados pela consulta de conteúdo.

Traduzir taxonomias e termos

As definições de taxonomia e os termos têm uma linha por locale. O EmDash registra quais linhas são traduções da mesma taxonomia ou do mesmo termo. As atribuições de conteúdo usam essa identidade compartilhada, de modo que uma atribuição feita em um locale é resolvida para o termo traduzido em outro locale quando ele existe.

Uma definição de taxonomia divide seus campos entre a taxonomia e cada locale:

CampoPertence aEfeito
nameTaxonomiaFixo após a criação. A definição de cada locale usa o mesmo nome.
hierarchical, collectionsTaxonomiaIguais em todos os locales. Alterar qualquer um deles por meio de qualquer locale o altera para todos os locales.
label, labelSingularLocaleA definição de cada locale tem os seus próprios.

Uma definição criada para um nome que já existe em outro locale entra nessa taxonomia, com ou sem translationOf, e adota seus hierarchical e collections. Criá-la com valores diferentes falha; altere-os com uma atualização. Um locale sem definição própria continua listando os termos da taxonomia e mostra o rótulo do primeiro locale de sua cadeia de fallback que tenha um, senão o rótulo do locale padrão, senão o rótulo do locale com o menor código de locale.

Use o seletor de locale em uma página de taxonomia para gerenciar os termos em cada locale configurado. Abra a caixa de diálogo de edição de um termo e use o painel Translations para adicionar ou abrir outro locale. Um termo traduzido pode usar um slug e um rótulo diferentes.

O pai e a posição de um termo são compartilhados por todos os locales. Uma tradução criada sem pai adota o pai e a posição do seu termo. Criar uma tradução sob um pai diferente, ou alterar o pai por meio de qualquer locale, move o termo em todos os locales.

Os helpers de consulta usam um locale explícito quando fornecido. Caso contrário, usam o locale da requisição atual e depois o padrão configurado. As buscas de um único termo seguem a cadeia de fallback configurada quando a tradução solicitada não existe.

Consulte Internacionalização (i18n) para roteamento por locale e configuração de fallback, e Trabalhar com conteúdo para editar entradas. A Referência da API JavaScript documenta os helpers de consulta de taxonomias. Para alterações programáticas, autentique-se com um token Bearer e adicione X-EmDash-Request: 1 a toda requisição que altere o estado. Consulte os endpoints de taxonomias para ver os corpos das requisições e as respostas.