Consultando Conteúdo
O EmDash fornece funções de consulta para recuperar conteúdo em suas páginas e componentes Astro. Essas funções seguem o padrão de coleções de conteúdo ao vivo do Astro, retornando resultados estruturados com tratamento de erros.
Funções de Consulta
Seção intitulada “Funções de Consulta”O EmDash exporta duas funções de consulta principais:
| Função | Propósito | Retorna |
|---|---|---|
getEmDashCollection | Recupera todas as entradas de um tipo de conteúdo | { entries, error } |
getEmDashEntry | Recupera uma única entrada por ID ou slug | { entry, error, isPreview } |
Importe-as de emdash:
import { getEmDashCollection, getEmDashEntry } from "emdash";Obter Todas as Entradas
Seção intitulada “Obter Todas as Entradas”Use getEmDashCollection para recuperar todas as entradas de um tipo de conteúdo:
astro title="src/pages/posts.astro"---import { getEmDashCollection } from "emdash";
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) { console.error("Failed to load posts:", error);}---
<ul> {posts.map((post) => ( <li>{post.data.title}</li> ))}</ul>Filtrar por Localidade
Seção intitulada “Filtrar por Localidade”Quando i18n está ativado, filtre por localidade para recuperar conteúdo em um idioma específico:
// French postsconst { entries: frenchPosts } = await getEmDashCollection("posts", { locale: "fr", status: "published",});
// Use a localidade da requisição atualconst { entries: localizedPosts } = await getEmDashCollection("posts", { locale: Astro.currentLocale, status: "published",});Para entradas únicas, passe locale como terceiro argumento:
const { entry: post } = await getEmDashEntry("posts", "my-post", { locale: Astro.currentLocale,});Quando locale é omitido, ele usa como padrão a localidade atual da requisição. Se não existir uma tradução para a localidade solicitada, a cadeia de fallback é seguida.
Filtrar por Status
Seção intitulada “Filtrar por Status”Recupere apenas conteúdo publicado ou rascunho:
// Only published postsconst { entries: published } = await getEmDashCollection("posts", { status: "published",});
// Apenas rascunhosconst { entries: drafts } = await getEmDashCollection("posts", { status: "draft",});Limitar Resultados
Seção intitulada “Limitar Resultados”Restrinja o número de entradas retornadas:
// Get the 5 most recent postsconst { entries: recentPosts } = await getEmDashCollection("posts", { status: "published", limit: 5,});Filtrar por Taxonomia
Seção intitulada “Filtrar por Taxonomia”Filtre entradas por categoria, tag ou termos de taxonomia personalizados:
// Posts in the "news" categoryconst { entries: newsPosts } = await getEmDashCollection("posts", { status: "published", where: { category: "news" },});
// Posts com a tag "javascript"const { entries: jsPosts } = await getEmDashCollection("posts", { status: "published", where: { tag: "javascript" },});
// Posts correspondendo a qualquer um de múltiplos termosconst { entries: featuredNews } = await getEmDashCollection("posts", { status: "published", where: { category: ["news", "featured"] },});O filtro where usa lógica OR quando múltiplos valores são fornecidos para uma única taxonomia.
Tratamento de Erros
Seção intitulada “Tratamento de Erros”Sempre verifique erros quando a confiabilidade for importante:
const { entries: posts, error } = await getEmDashCollection("posts");
if (error) { // Registre e trate de forma elegante console.error("Falha ao carregar posts:", error); return new Response("Erro do servidor", { status: 500 });}Obter uma Única Entrada
Seção intitulada “Obter uma Única Entrada”Use getEmDashEntry para recuperar uma entrada pelo seu ID ou slug:
astro title="src/pages/posts/[slug].astro"---import { getEmDashEntry } from "emdash";import { PortableText } from "emdash/ui";
const { slug } = Astro.params;const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) { return new Response("Erro do servidor", { status: 500 });}
if (!post) { return Astro.redirect("/404");}---
<article> <h1>{post.data.title}</h1> <PortableText value={post.data.content} /></article>Tipo de Retorno da Entrada
Seção intitulada “Tipo de Retorno da Entrada”getEmDashEntry retorna um objeto de resultado:
interface EntryResult<T> { entry: ContentEntry<T> | null; // null if not found error?: Error; // Only set for actual errors (not "not found") isPreview: boolean; // true if viewing preview/draft content}
interface ContentEntry<T> { id: string; data: T; edit: EditProxy; // Visual editing annotations}O objeto data dentro de entry contém todos os campos definidos para o tipo de conteúdo. O proxy edit fornece anotações para edição visual (veja abaixo).
Modo de Visualização
Seção intitulada “Modo de Visualização”O EmDash gerencia a visualização automaticamente via middleware. Quando uma URL contém um token _preview válido, o middleware o verifica e configura o contexto da requisição. Suas funções de consulta então servem conteúdo de rascunho sem nenhum parâmetro especial:
astro title="src/pages/posts/[...slug].astro"---import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;
// Nenhum tratamento especial de visualização necessário — o middleware faz isso automaticamenteconst { entry, isPreview, error } = await getEmDashEntry("posts", slug);
if (error) { return new Response("Erro do servidor", { status: 500 });}
if (!entry) { return Astro.redirect("/404");}---
{isPreview && ( <div class="preview-banner"> Viewing preview. This content is not published. </div>)}
<article> <h1>{entry.data.title}</h1> <PortableText value={entry.data.content} /></article>Edição Visual
Seção intitulada “Edição Visual”Cada entrada retornada pelas funções de consulta inclui um proxy edit para anotar seus templates. Espalhe-o nos elementos para habilitar a edição inline para editores autenticados:
<article {...entry.edit}> <h1 {...entry.edit.title}>{entry.data.title}</h1> <div {...entry.edit.content}> <PortableText value={entry.data.content} /> </div></article>No modo de edição, {...entry.edit.title} produz um atributo data-emdash-ref que a barra de ferramentas de edição visual usa para habilitar a edição inline. Em produção, os spreads do proxy não produzem saída — custo de execução zero.
Ordenando Resultados
Seção intitulada “Ordenando Resultados”getEmDashCollection não garante ordem de classificação. Ordene os resultados em seu template:
const { entries: posts } = await getEmDashCollection("posts", { status: "published",});
// Ordenar por data de publicação, mais recente primeiroconst sorted = posts.sort( (a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),);Padrões Comuns de Ordenação
Seção intitulada “Padrões Comuns de Ordenação”// Alphabetical by titleposts.sort((a, b) => a.data.title.localeCompare(b.data.title));
// Por campo de ordem personalizadoposts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// Ordem aleatóriaposts.sort(() => Math.random() - 0.5);Tipos TypeScript
Seção intitulada “Tipos TypeScript”Gere tipos TypeScript para suas coleções:
npx emdash typesIsso cria .emdash/types.ts com interfaces para cada coleção. Use-os para segurança de tipos:
import { getEmDashCollection, getEmDashEntry } from "emdash";import type { Post } from "../../.emdash/types";
// Consulta de coleção com segurança de tiposconst { entries: posts } = await getEmDashCollection<Post>("posts");// posts é ContentEntry<Post>[]
// Consulta de entrada com segurança de tiposconst { entry: post } = await getEmDashEntry<Post>("posts", "my-post");// post é ContentEntry<Post> | nullRenderização Estática vs. no Servidor
Seção intitulada “Renderização Estática vs. no Servidor”O conteúdo do EmDash funciona tanto com páginas estáticas quanto renderizadas no servidor.
Estático (Pré-renderizado)
Seção intitulada “Estático (Pré-renderizado)”Para páginas estáticas, use getStaticPaths para gerar rotas no momento da build:
astro title="src/pages/posts/[slug].astro"---import { getEmDashCollection, getEmDashEntry } from "emdash";
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);---Renderizado no Servidor
Seção intitulada “Renderizado no Servidor”Para páginas renderizadas no servidor, consulte o conteúdo diretamente:
astro title="src/pages/posts/[slug].astro"---export const prerender = false;
import { getEmDashEntry } from "emdash";
const { slug } = Astro.params;const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) { return new Response("Server error", { status: 500 });}
if (!post) { return new Response(null, { status: 404 });}---Considerações de Desempenho
Seção intitulada “Considerações de Desempenho”O EmDash usa as coleções de conteúdo ao vivo do Astro, que lidam com o cache automaticamente. Para páginas renderizadas no servidor, considere adicionar cabeçalhos de cache HTTP:
---const { entries: posts } = await getEmDashCollection("posts", { status: "published",});
// Cache por 5 minutosAstro.response.headers.set("Cache-Control", "public, max-age=300");---Evite Consultas Redundantes
Seção intitulada “Evite Consultas Redundantes”Consulte uma vez e passe os dados para os componentes:
astro title="src/pages/index.astro"---import { getEmDashCollection } from "emdash";import PostList from "../../components/PostList.astro";import Sidebar from "../../components/Sidebar.astro";
// Consulte uma vezconst { entries: posts } = await getEmDashCollection("posts", { status: "published",});
const featured = posts.filter((p) => p.data.featured);const recent = posts.slice(0, 5);---
<PostList posts={featured} /><Sidebar posts={recent} />Próximos Passos
Seção intitulada “Próximos Passos”- Criar um Blog - Construa um blog completo
- Taxonomias - Filtrar por categorias e tags
- Trabalhando com Conteúdo - Operações CRUD de administração
- Internacionalização - Conteúdo e traduções multilíngues