Pular para o conteúdo

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.

O EmDash exporta duas funções de consulta principais:

FunçãoPropósitoRetorna
getEmDashCollectionRecupera todas as entradas de um tipo de conteúdo{ entries, error }
getEmDashEntryRecupera uma única entrada por ID ou slug{ entry, error, isPreview }

Importe-as de emdash:

import { getEmDashCollection, getEmDashEntry } from "emdash";

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>

Quando i18n está ativado, filtre por localidade para recuperar conteúdo em um idioma específico:

// French posts
const { entries: frenchPosts } = await getEmDashCollection("posts", {
locale: "fr",
status: "published",
});
// Use a localidade da requisição atual
const { 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.

Recupere apenas conteúdo publicado ou rascunho:

// Only published posts
const { entries: published } = await getEmDashCollection("posts", {
status: "published",
});
// Apenas rascunhos
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});

Restrinja o número de entradas retornadas:

// Get the 5 most recent posts
const { entries: recentPosts } = await getEmDashCollection("posts", {
status: "published",
limit: 5,
});

Filtre entradas por categoria, tag ou termos de taxonomia personalizados:

// Posts in the "news" category
const { 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 termos
const { 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.

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 });
}

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>

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

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 automaticamente
const { 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>

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.

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 primeiro
const sorted = posts.sort(
(a, b) => (b.data.publishedAt?.getTime() ?? 0) - (a.data.publishedAt?.getTime() ?? 0),
);
// Alphabetical by title
posts.sort((a, b) => a.data.title.localeCompare(b.data.title));
// Por campo de ordem personalizado
posts.sort((a, b) => (a.data.order ?? 0) - (b.data.order ?? 0));
// Ordem aleatória
posts.sort(() => Math.random() - 0.5);

Gere tipos TypeScript para suas coleções:

Terminal window
npx emdash types

Isso 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 tipos
const { entries: posts } = await getEmDashCollection<Post>("posts");
// posts é ContentEntry<Post>[]
// Consulta de entrada com segurança de tipos
const { entry: post } = await getEmDashEntry<Post>("posts", "my-post");
// post é ContentEntry<Post> | null

O conteúdo do EmDash funciona tanto com páginas estáticas quanto renderizadas no servidor.

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

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 });
}
---

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 minutos
Astro.response.headers.set("Cache-Control", "public, max-age=300");
---

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 vez
const { 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} />