As coleções são a base do modelo de conteúdo do EmDash. Cada coleção representa um tipo de conteúdo (posts, páginas, produtos) e contém definições de campos que determinam o formato dos seus dados.
Criar coleções
Crie coleções no painel de administração em Tipos de conteúdo. Cada coleção tem:
| Propriedade | Descrição |
|---|---|
slug | Identificador seguro para URL (ex.: posts, products) |
label | Nome de exibição (ex.: «Blog Posts») |
labelSingular | Forma singular (ex.: «Post») |
description | Descrição opcional para editoras |
icon | Nome do ícone Lucide na barra lateral do admin |
supports | Recursos como rascunhos, revisões, pré-visualização, agendamento, busca, SEO |
Recursos da coleção
Ao criar uma coleção, ative os recursos necessários:
| Recurso | Descrição |
|---|---|
drafts | Fluxo rascunho/publicado |
revisions | Histórico de conteúdo com instantâneos de versão |
preview | URLs de pré-visualização assinadas para rascunhos |
scheduling | Agendar publicação em data futura |
// Exemplo de coleção com todos os recursos
{
slug: "posts",
label: "Blog Posts",
labelSingular: "Post",
supports: ["drafts", "revisions", "preview", "scheduling"]
}
Tipos de campo
O EmDash suporta 15 tipos de campo mapeados para tipos de coluna SQLite:
Campos de texto
string
Texto curto. Mapeado para a coluna TEXT.
{ slug: "title", type: "string", label: "Title" } text
Área de texto multilinha. Mapeada para a coluna TEXT.
{ slug: "excerpt", type: "text", label: "Excerpt" } slug
Campo de identificador seguro para URL. Mapeado para a coluna TEXT.
{ slug: "handle", type: "slug", label: "URL Handle" } Conteúdo rico
portableText
Editor de texto rico (TipTap/ProseMirror). Armazenado como JSON.
{ slug: "content", type: "portableText", label: "Content" }Portable Text é um formato em blocos que preserva a estrutura sem HTML embutido.
json
Dados JSON arbitrários. Armazenados como JSON.
{ slug: "metadata", type: "json", label: "Custom Metadata" } Números
number
Números decimais. Mapeados para a coluna REAL.
{ slug: "price", type: "number", label: "Price" } integer
Números inteiros. Mapeados para a coluna INTEGER.
{ slug: "quantity", type: "integer", label: "Stock Quantity" } Booleanos e datas
boolean
Alternância verdadeiro/falso. Mapeada para INTEGER (0/1).
{ slug: "featured", type: "boolean", label: "Featured Post" } datetime
Seletor de data e hora. Armazenado como string ISO 8601.
{ slug: "eventDate", type: "datetime", label: "Event Date" } Seleção
select
Uma opção de uma lista. Mapeada para a coluna TEXT.
{
slug: "status",
type: "select",
label: "Product Status",
validation: {
options: ["active", "discontinued", "coming_soon"]
}
} multiSelect
Várias opções de uma lista. Armazenado como array JSON.
{
slug: "features",
type: "multiSelect",
label: "Product Features",
validation: {
options: ["wireless", "waterproof", "eco-friendly"]
}
} Mídia e referências
image
Seletor de imagem na biblioteca de mídia. Armazena o ID da mídia como TEXT.
{ slug: "featuredImage", type: "image", label: "Featured Image" } file
Seletor de arquivo na biblioteca de mídia. Armazena o ID da mídia como TEXT.
{ slug: "attachment", type: "file", label: "PDF Attachment" } reference
Referência a uma entrada de outra coleção. Armazena o ID da entrada como TEXT.
{
slug: "author",
type: "reference",
label: "Author",
options: {
collection: "authors"
}
} Propriedades dos campos
Cada campo suporta estas propriedades:
| Propriedade | Tipo | Descrição |
|---|---|---|
slug | string | Nome da coluna no banco |
label | string | Rótulo na UI do admin |
type | FieldType | Um dos 15 tipos de campo |
required | boolean | Se o campo deve ter valor |
unique | boolean | Se os valores devem ser únicos entre entradas |
defaultValue | unknown | Valor padrão para novas entradas |
validation | object | Regras de validação específicas do tipo |
widget | string | Identificador de widget personalizado |
options | object | Configuração específica do widget |
sortOrder | number | Ordem de exibição no editor |
Regras de validação
O objeto validation varia conforme o tipo de campo:
interface FieldValidation {
required?: boolean; // todos os tipos
min?: number; // number, integer
max?: number; // number, integer
minLength?: number; // string, text
maxLength?: number; // string, text
pattern?: string; // string (regex)
options?: string[]; // select, multiSelect
}
Exemplo com validação:
{
slug: "email",
type: "string",
label: "Email Address",
required: true,
unique: true,
validation: {
pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
}
}
Opções de widget
O objeto options configura o comportamento de UI específico do campo:
interface FieldWidgetOptions {
rows?: number; // text (linhas do textarea)
showPreview?: boolean; // image, file
collection?: string; // reference (coleção alvo)
allowMultiple?: boolean; // reference (várias referências)
[key: string]: unknown; // opções de widget personalizadas
}
Exemplo de campo de referência:
{
slug: "relatedProducts",
type: "reference",
label: "Related Products",
options: {
collection: "products",
allowMultiple: true
}
}
Consultar coleções
Use as funções de consulta fornecidas para buscar conteúdo. Elas seguem o padrão de coleções ao vivo do Astro e retornam resultados estruturados:
import { getEmDashCollection, getEmDashEntry } from "emdash";
// Todas as entradas — retorna { entries, error }
const { entries: posts } = await getEmDashCollection("posts");
// Filtrar por status
const { entries: drafts } = await getEmDashCollection("posts", {
status: "draft",
});
// Limitar resultados
const { entries: recent } = await getEmDashCollection("posts", {
limit: 5,
});
// Filtrar por taxonomia
const { entries: newsPosts } = await getEmDashCollection("posts", {
where: { category: "news" },
});
// Uma entrada por slug — retorna { entry, error, isPreview }
const { entry: post } = await getEmDashEntry("posts", "my-post-slug");
// Tratamento de erros
const { entries, error } = await getEmDashCollection("posts");
if (error) {
console.error("Failed to load posts:", error);
}
Geração de tipos
Execute npx emdash types para gerar tipos TypeScript a partir do seu esquema:
// .emdash/types.ts (gerado)
export interface Post {
title: string;
content: PortableTextBlock[];
excerpt?: string;
featuredImage?: string;
author: string; // ID de referência
}
export interface Product {
title: string;
price: number;
description: PortableTextBlock[];
}
Mapeamento no banco
Os tipos de campo correspondem aos tipos de coluna SQLite:
| Tipo de campo | Tipo SQLite | Notas |
|---|---|---|
string | TEXT | |
text | TEXT | |
slug | TEXT | |
number | REAL | ponto flutuante 64 bits |
integer | INTEGER | inteiro com sinal 64 bits |
boolean | INTEGER | 0 ou 1 |
datetime | TEXT | formato ISO 8601 |
select | TEXT | |
multiSelect | JSON | array de strings |
portableText | JSON | array de blocos |
image | TEXT | ID de mídia |
file | TEXT | ID de mídia |
reference | TEXT | ID de entrada |
json | JSON | JSON arbitrário |
Próximos passos
Modelo de conteúdo
Entenda a abordagem orientada ao banco de dados.
Taxonomias
Organize conteúdo com categorias e tags.
Biblioteca de mídia
Gerencie imagens e arquivos.