🌱 Seed

Coleções e @each

Coleções permitem iterar sobre listas de conteúdo diretamente no template .seed usando o componente @each. Defina no seed.yaml, crie um diretório com arquivos .seed, e use @each para listar os itens.

O que é uma coleção

Uma coleção é um diretório de arquivos .seed dentro de src/. Cada arquivo representa um item, e o front matter de cada arquivo define os campos acessíveis no template via {prefixo-campo}.

Exemplos de uso:

Configuração no seed.yaml

Declare suas coleções na chave collections do seed.yaml:

```yaml
collections:
  team:                    # nome da coleção → @each team
    dir: team              # diretório: src/team/
    sort: name             # campo de ordenação (default: title)
    order: asc             # asc | desc (default: asc)
  projects:
    dir: projects          # src/projects/
    sort: publish_date
    order: desc
```

Estrutura do projeto

```
src/
├── team/
│   ├── list.layout        ← layout da listagem (opcional)
│   ├── item.layout        ← layout de cada membro (opcional)
│   ├── ana.seed
│   ├── lucas.seed
│   └── maria.seed
├── projects/
│   ├── list.layout
│   ├── item.layout
│   ├── ada.seed
│   └── seed.seed
└── index.seed
```

Cada arquivo .seed dentro do diretório da coleção é um item. O front matter define os campos:

```seed
---
name: Ana Silva
role: CTO
photo: /static/img/ana.jpg
---

@p
  Ana lidera a engenharia com 15 anos de experiência em fintechs.
```

Usando @each no template

O componente @each itera sobre uma coleção registrada. Tudo que está indentado abaixo dele é repetido para cada item:

```seed
@each team
  @div class=flex items-center gap-4 p-4 border rounded-lg
    @img src={team-photo}, class=w-12 h-12 rounded-full
    @div
      @h3
        {team-name}
      @p class=text-sm text-gray-500
        {team-role}
```

Se a coleção team tiver 3 membros, o bloco acima gera 3 cards — um para cada pessoa.

Prefixo de variáveis

As variáveis dentro de @each usam o padrão {prefixo-campo}. O prefixo é derivado automaticamente do nome da coleção, removendo o s final quando houver:

ColeçãoPrefixoVariáveis de exemplo
postspost{post-title}, {post-url}, {post-publish_date}
projectsproject{project-name}, {project-url}
teamteam{team-name}, {team-role}
testimonialstestimonial{testimonial-text}, {testimonial-author}

Cada campo do front matter do .seed vira uma variável com {prefixo-campo}.

Layouts

Cada coleção pode ter dois layouts opcionais no seu diretório:

ArquivoPropósito
list.layoutPágina de listagem da coleção (/team/index.html), com @each para iterar
item.layoutLayout aplicado a cada .seed individual da coleção

Os nomes são configuráveis no seed.yaml:

```yaml
collections:
  cases:
    dir: cases
    list_layout: gallery    # → src/cases/gallery.layout
    item_layout: case       # → src/cases/case.layout
```

Resolução (prioridade)

  1. Projetosrc/<dir>/<nome>.layout
  2. Temathemes/<tema>/<dir>/<nome>.layout
  3. Fallbacksrc/default.layout (para item) ou listagem embutida (para list)

Exemplo: list.layout

```seed
---
title: Nossa Equipe
---
@section class=max-w-5xl mx-auto py-20
  @h1
    Equipe

  @div class=grid gap-8 md:grid-cols-3
    @each team
      @div class=text-center
        @img src={team-photo}, class=w-24 h-24 rounded-full mx-auto
        @h3
          {team-name}
        @p class=text-gray-500
          {team-role}
```

Exemplo: item.layout

```seed
---
title: Equipe
---
@article class=max-w-3xl mx-auto py-20 px-6
  @h1
    {title}
  @p class=text-gray-500
    {role}
  @div class=prose
    {content}
```

Convenções

RegraExemploResultado
Campos com _ são internosCampo _file num itemNão é exposto no template
Listas viram stringtags: [a, b]{post-tags}"a, b"
Campo inexistente{post-inexistente}Permanece literal no HTML

Datas, arquivos e autoria

Coleções que ordenam ou agrupam por data usam o campo publish_date do front matter (não date — veja Front Matter). Se a coleção define sort: publish_date ou dates: day/dates: month, todo item precisa ter publish_date — sem ele, o build falha apontando o arquivo.

```yaml
collections:
  blog:
    dir: blog
    sort: publish_date
    order: desc
    tags: true      # gera /blog/tags/<slug>/ com @each tags
    dates: month     # gera /blog/<YYYY-MM>/ com @each dates
    author:
      name: Jane Doe # autor padrão de todo item — ver abaixo
```

Com tags: true, cada item pode declarar tags: [a, b] no front matter; o Seed gera uma página de arquivo por tag e registra @each tags com {tag-name}, {tag-url}, {tag-count}, {tag-active}. Com dates: day ou dates: month, o Seed gera páginas de arquivo por dia/mês (noindex, follow) e registra @each dates com {date-name}, {date-url}, {date-count}, {date-active} (mais recente primeiro).

author: na coleção define o autor padrão de todo item — tanto no JSON-LD quanto na variável {author_name} usada em item.layout/list.layout. Uma página pode sobrescrever com seu próprio author_name, ou remover a autoria com author: false. Detalhes completos da precedência em SEO & Metadados.

Paginação de Coleções

Quando uma coleção cresce, exibir todos os itens em uma única página pode prejudicar a performance e a experiência do usuário. O Seed oferece um sistema de paginação automática que divide o conteúdo em múltiplas páginas físicas.

1. Configuração

Para ativar a paginação, adicione a chave per_page na configuração da coleção no seed.yaml:

```yaml
collections:
  blog:
    per_page: 10          # Exibe 10 itens por página
```

O valor padrão é 0, que mantém todos os itens em uma única página (sem paginação).

2. Estrutura de URLs

Ao ativar a paginação, o Seed gera automaticamente uma estrutura de diretórios para as páginas subsequentes:

Essa estrutura é ideal para SEO e permite que os usuários naveguem diretamente para páginas específicas.

3. Variáveis de Navegação

Dentro do seu list.layout (ou arquivo que contém o @each), o Seed injeta variáveis especiais de metadados. Você pode usá-las para criar controles de navegação (anterior/próximo, contador de páginas, etc.):

VariávelDescrição
{page}Número da página atual (inteiro: 1, 2, 3...)
{total_pages}Quantidade total de páginas geradas
{total_items}Número total de itens na coleção (antes de filtrar por página)
{prev_url}Caminho da página anterior. Fica vaziO na primeira página.
{next_url}Caminho da próxima página. Fica vazia na última página.
{prev_title}Sugestão de título amigável: "Página 1" (ou o número da página anterior).
{next_title}Sugestão de título amigável: "Página 3" (ou o número da próxima página).

4. Guia de Implementação (Exemplo Completo)

Abaixo, um exemplo de como implementar uma paginação robusta usando componentes utilitários para condicionalmente exibir os links:

```seed
// No seu list.layout
@section
  @h1
    Artigos

  @div class=grid gap-6
    @each blog
      @article
        @h2
          {blog-title}
        @p
          {blog-description}

  // Navegação
  @nav class=flex items-center justify-between mt-12 py-8 border-t
    @div
      @if {prev_url}
        @a href={prev_url}, class=btn-pagination
          ← {prev_title}

    @span class=text-gray-500
      Página {page} de {total_pages}

    @div
      @if {next_url}
        @a href={next_url}, class=btn-pagination
          {next_title} →
```
💡

O Seed é inteligente: se você definir per_page: 10 mas tiver apenas 8 itens, ele gerará apenas a página principal e as variáveis de navegação (next_url, etc.) ficarão vazias, ocultando os botões automaticamente se você usar o padrão @if.

Se a coleção estiver vazia, o bloco @each não gera nenhum HTML — sem erros, sem output.

Se a coleção não foi registrada (o nome não existe no seed.yaml), o Seed exibe um erro inline visível na página para facilitar depuração.

Múltiplas coleções na mesma página

Você pode usar quantos @each quiser na mesma página, cada um com uma coleção diferente:

```seed
@section
  @h2
    Equipe
  @each team
    @p
      {team-name} — {team-role}

@section
  @h2
    Projetos
  @each projects
    @p
      {project-name} — {project-description}
```
💡

O blog é uma coleção especial com funcionalidades extras (listing page automática, filtragem de drafts, campos pré-definidos). Veja Blog.

Feito com ❤️ e Seed