Logotipo Hedhog

Receba novidades do Hedhog no seu e-mail

Novos lançamentos, receitas e breaking changes — sem spam.

Submódulo cms

layouts

Gerencia layouts de página reutilizáveis (um arranjo nomeado de regiões, como header/main/sidebar) que as páginas referenciam via layout_slug, além do CRUD sobre as regiões de cada layout.

Caminho de origem: libraries/cms/src/cms-layout.controller.ts, cms-layout.service.ts

Arquivo do módulo: cms.module.ts

Introdução

O submódulo Layouts é dono de `cms_layout` e de sua tabela filha `cms_layout_region`. Um layout tem um `type` (vertical, horizontal, grid, blog_post, custom), um `schema` e um `default_config` opcionais (ambos JSON de forma livre), um flag `is_active` e um nome/descrição traduzidos por locale, armazenados em uma tabela complementar `cms_layout_locale`. As regiões pertencem a exatamente um layout via `layout_id`, carregam um `code` que deve ser único dentro daquele layout (por exemplo, "header", "main", "sidebar"), uma `order`, um blob JSON `config` opcional e seu próprio nome/descrição traduzidos por locale em `cms_layout_region_locale`. O `layout_slug` de uma página é resolvido para `layout_id` no momento de criação/atualização da página pelo submódulo Pages, e toda instância de componente posicionada em uma página deve referenciar um dos códigos de região do próprio layout dessa página — é essa relação região/layout que o `saveComponents` do submódulo Pages valida.

A criação e a atualização, tanto de layouts quanto de regiões, seguem o mesmo padrão de duas etapas usado em todo o módulo CMS: a linha base é escrita primeiro e, em seguida, cada entrada do mapa `locale` sofre upsert — atualizada se já existir uma linha `cms_layout_locale`/`cms_layout_region_locale` para aquele locale, ou criada caso contrário — de modo que enviar uma tradução para apenas um locale nunca afeta os demais. Nem layouts nem regiões são excluídos logicamente: `DELETE /cms/layouts/:id` e `DELETE /cms/layouts/:id/regions/:regionId` emitem um `.delete()` físico do Prisma. As exclusões de região têm ainda escopo em seu layout pai (`layout_id` deve corresponder ao `:id` no caminho), de modo que um ID de região pertencente a um layout diferente retorna 404 em vez de excluir entre layouts.

Não há guarda explícita em `CmsLayoutService` contra a exclusão de um layout que páginas ainda referenciam — a proteção vem inteiramente do banco de dados: `cms_page.layout_id` é declarado `onDelete: RESTRICT` no YAML da tabela, de modo que tentar excluir um layout em uso se manifesta como uma falha bruta de restrição de foreign key, e não como um erro amigável no nível da aplicação. O formato da resposta também inclui um campo `pages_count`, destinado a mostrar quantas páginas usam um layout, mas as consultas Prisma subjacentes em `list()` e `getById()` não solicitam uma relação `_count` — `mapLayout()` lê `layout._count?.cms_page ?? 0`, que na prática é sempre `undefined`, de modo que `pages_count` atualmente reporta `0` para todos os layouts, independentemente do uso real.

Diferentemente de Pages, onde o `cms-editor` pode criar e atualizar conteúdo, todo endpoint de escrita deste submódulo (tanto de layouts quanto de regiões) é restrito apenas a `admin`/`admin-cms` — os editores de conteúdo podem ler os layouts para escolher um para uma página, mas não podem definir nem modificar layouts ou suas regiões.

Endpoints HTTP

9 endpoints

Listagem completa de layouts (não paginada), cada um com suas regiões incorporadas, ordenados por ID. Nomes/descrições são resolvidos para o locale da requisição (com fallback para a primeira tradução disponível).

Query
slug? — filter to a single layout by slug

Cria um novo layout e suas linhas de nome/descrição por locale.

Body

FieldTypeRequiredNotes
slugstringyes
typeCmsLayoutType (vertical | horizontal | grid | blog_post | custom)noDefault: vertical
is_activebooleannoDefault: true
schemaobjectno
default_configobjectno
localeRecord<string, { name: string; description?: string }>yese.g. { "en": { "name": "...", "description": "..." } } — upserts one locale row per key

Obtém um único layout com suas regiões, localizado para o locale da requisição.

Params
id (int)

Atualiza um layout (mesmos campos da criação, todos opcionais). As entradas de locale sofrem upsert individualmente, deixando intactos os locales não informados.

Params
id (int)

Exclui fisicamente um layout. Não protegido no nível do serviço — falha com um erro de foreign key do banco de dados se alguma página ainda o referenciar (cms_page.layout_id é RESTRICT).

Params
id (int)

Lista as regiões de um layout, ordenadas pelo campo order, localizadas para o locale da requisição.

Params
id (int) — layout ID

Adiciona uma região a um layout e suas linhas de nome/descrição por locale.

Params
id (int) — layout ID

Body

FieldTypeRequiredNotes
codestringyesUnique within the layout, e.g. "header", "main"
ordernumbernoDefault: 0
configobjectno
localeRecord<string, { name: string; description?: string }>yese.g. { "en": { "name": "...", "description": "..." } } — upserts one locale row per key

Atualiza uma região (mesmos campos da criação, todos opcionais). Rejeita com 404 se regionId não pertencer ao layout id.

Params
id (int) — layout ID, regionId (int)

Exclui fisicamente uma região. Rejeita com 404 se regionId não pertencer ao layout id. Quaisquer linhas cms_page_component apontando para a região estão sujeitas à sua foreign key RESTRICT, de modo que excluir uma região ainda em uso por componentes de página falhará no nível do banco de dados.

Params
id (int) — layout ID, regionId (int)