Blocks
A pasta Blocks concentra os blocos reutilizáveis que podem ser disponibilizados no CMS para páginas configuradas com content_for_page.
Cada bloco deve possuir dois arquivos com o mesmo nome base:
Blocks/<type>.html: responsável pela renderização do bloco na página.Blocks/<type>.schema.json: responsável por descrever os campos editáveis do bloco no CMS e o contrato usado na validação do salvamento.
Exemplo de estrutura
Blocks/
banner_button.html
banner_button.schema.json
banner_carousel.html
banner_carousel.schema.json
button_carousel.html
button_carousel.schema.json
image_showcase.html
image_showcase.schema.json
product_carousel.html
product_carousel.schema.jsonRegras importantes
- O nome do arquivo deve ser igual ao
typedo bloco. - Para um bloco com
type: "banner_button", os arquivos esperados sãoBlocks/banner_button.htmleBlocks/banner_button.schema.json. - O arquivo
.htmlé carregado na renderização da página. - O arquivo
.schema.jsoné carregado para montar os campos do CMS e validar os dados enviados no salvamento. - Se o
.schema.jsonnão existir, o bloco não poderá ser salvo. - Se o
.htmlnão existir, o bloco não poderá ser renderizado corretamente.
Guia de criação de schema.json
O schema.json define como o bloco aparece para edição no CMS e quais valores a plataforma aceita.
Estrutura base
{
"name": "Banner com botão",
"type": "banner_button",
"settings": [
{
"label": "Título principal",
"name": "title",
"type": "text",
"required": false
}
]
}Propriedades do bloco
| Propriedade | Tipo | Obrigatória | Descrição |
|---|---|---|---|
| name | string | recomendada | Nome amigável exibido para quem está configurando o bloco. |
| type | string | sim | Identificador técnico do bloco. Deve ser o mesmo valor usado em content_for_page e no nome dos arquivos. |
| settings | array | sim | Lista de campos editáveis do bloco. |
Propriedades de cada item em settings
settings| Propriedade | Tipo | Obrigatória | Descrição |
|---|---|---|---|
| label | string | recomendada | Texto exibido no CMS para o usuário da plataforma. |
| name | string | sim | Nome técnico do campo. Ele vira a chave dentro de content e pode ser acessado no HTML por block_data.<name>. |
| type | string | sim | Tipo do campo. |
| required | boolean | não | Define se o campo é obrigatório. |
| options | array | obrigatória para select | Lista de opções válidas para campos fechados (select/options). |
Tipos de campos suportados em settings
settings| Tipo | Descrição |
|---|---|
| text | Texto simples. O valor deve ser uma string com tamanho máximo limitado. É o tipo padrão. |
| string | Alias de text. Comportamento idêntico — aceita string com limite de tamanho. |
| number | Valor numérico. Aceita apenas valores do tipo número (inteiro ou decimal). |
| url | URL. Aceita string e rejeita URLs perigosas. |
| image_picker | Seletor de imagem. Aceita string (URL ou caminho) e rejeita URLs perigosas. |
| color | Cor. Aceita string em formato hexadecimal (#RGB, #RRGGBB, #RRGGBBAA) ou rgba. |
| select | Seleção única. O valor deve ser uma das opções definidas na lista options. |
| options | Alias de select. Comportamento idêntico — valida contra a lista de opções permitidas. |
| checkbox | Caixa de seleção. Aceita apenas valores booleanos (true ou false). |
| boolean | Alias de checkbox. Comportamento idêntico. |
hotsite_products | ID de hotsite. Aceita apenas inteiro positivo. O Storefront busca automaticamente os produtos desse hotsite e os injeta em block_data.<name> como uma lista de produtos. Máximo de 50 produtos retornados. |
product_list | Lista de IDs de produtos. Aceita array não vazio de inteiros positivos. Os produtos são buscados e injetados em block_data.<name> respeitando a ordem declarada. IDs inválidos são ignorados. Máximo de 50 IDs. |
range | valor numérico com mínimo/máximo. |
Exemplo completo com vários tipos
{
"name": "Hero promocional",
"type": "promo_hero",
"settings": [
{
"label": "Título",
"name": "title",
"type": "text",
"required": true
},
{
"label": "Produtos por linha",
"name": "items_visible",
"type": "number",
"required": false
},
{
"label": "Link do botão",
"name": "button_url",
"type": "url",
"required": false
},
{
"label": "Imagem principal",
"name": "background_image",
"type": "image_picker",
"required": true
},
{
"label": "Cor do texto",
"name": "text_color",
"type": "color",
"required": false
},
{
"label": "Tema visual",
"name": "theme",
"type": "select",
"required": false,
"options": [
{ "label": "Claro", "value": "light" },
{ "label": "Escuro", "value": "dark" }
]
},
{
"label": "Exibir selo",
"name": "show_badge",
"type": "checkbox",
"required": false
}
]
}Exemplos isolados
- Campo select:
{
"label": "Tamanho do título",
"name": "title_size",
"type": "select",
"required": false,
"options": [
{ "label": "Pequeno", "value": "sm" },
{ "label": "Médio", "value": "md" },
{ "label": "Grande", "value": "lg" },
{ "label": "Extra grande", "value": "xl" }
]
}- Campo color:
{
"label": "Cor do texto",
"name": "text_color",
"type": "color",
"required": false
}- Campo image_picker:
{
"label": "Imagem",
"name": "image",
"type": "image_picker",
"required": true
}Como os dados chegam no HTML do bloco
No arquivo Blocks/<type>.html, os valores das configurações do bloco ficam disponíveis em block_data.
Exemplo:
{{~
title = block_data.title
if title | string.empty
title = "Título padrão"
end
~}}
<section>
<h2>{{ title }}</h2>
</section>
Isso significa que o name de cada item em settings deve ser pensado como uma chave de dados reutilizável tanto pelo CMS quanto pelo template.
Blocos em templates que atendem várias URLs
Um mesmo template pode atender várias URLs (ver urlMatch em
pages.json), e cada uma dessas
URLs pode ter um layout exclusivo configurado pelo lojista no Design Studio.
Isso não muda nada na criação do bloco: o mesmo par
Blocks/<type>.html + Blocks/<type>.schema.json atende tanto o layout do
template quanto os layouts exclusivos por URL. Não existe schema, campo ou flag
específica para layout exclusivo.
O que muda é a recomendação de como escrever o bloco:
- Não presuma uma URL fixa dentro do bloco. Se o bloco precisa de um link,
um título ou uma imagem diferente por página, isso deve ser um campo em
settings, editável pelo lojista — não uma condicional no Scriban baseada
na URL corrente. - Não use o bloco para diferenciar páginas. O caminho suportado para "esta
URL precisa de um banner diferente" é o layout exclusivo por URL no Design
Studio, não uma ramificação dentro do HTML do bloco. - O bloco continua recebendo apenas
block_data. O conteúdo entregue em
block_dataé o do layout que venceu a resolução para aquela URL — exclusivo
se houver, do template caso contrário. O bloco não precisa (e não consegue)
saber qual dos dois foi usado.
Resumo
Para disponibilizar um bloco no CMS desta primeira versão, a agência deve seguir este fluxo:
- Criar
Blocks/<type>.html. - Criar
Blocks/<type>.schema.json. - O
content_for_pagepode ser declarado em dois níveis:- No item de
customs: vale para as URLs atendidas por aquele custom. - No nível da página (ex.: no objeto
hotsite): vale para as URLs atendidas pelo template base da página; também é usado como fallback quando o custom correspondente não declaracontent_for_pagepróprio.
- No item de
- Garantir que os nomes dos campos em
settings[].namesejam os mesmos usados noblock_datado HTML. - Validar se os tipos escolhidos no
schemaestão entre os suportados pela plataforma.
Updated 15 days ago

