Introdução
Defina campos personalizados para seu conteúdo sem tocar no código.
🎯 O que este módulo faz?
O módulo AttributesSets permite que você use campos personalizados para seu conteúdo (produtos, páginas, formulários, etc.) sem codificá-los diretamente em sua aplicação.
Pense nisso como um construtor de formulários para seus dados - você define quais campos precisa, e o OneEntry cuida do resto.
📖 Explicação Simples
Imagine que você está construindo uma loja online. Cada produto precisa de:
- Nome (texto).
- Preço (número).
- Imagem (foto).
- Descrição (texto longo).
- Categoria (dropdown).
Em vez de codificar esses campos em seu aplicativo, você usa Attributes para defini-los no painel de administração do OneEntry. Então você pode:
- Adicionar novos campos a qualquer momento (sem mudanças de código!).
- Reutilizar campos em diferentes tipos de conteúdo.
- Alterar tipos de campo sem precisar redeployar.
- Gerenciar toda a estrutura de conteúdo em um só lugar.
Exemplo do mundo real:
Sem Attributes (codificado):
- Código: const product = { name: 'Nome do produto', price: 150, image: '', description: '' }
- Para adicionar o campo "cor" → Mudar o código, redeploy, esperar.
Com Attributes (dinâmico):
- Código: const { name, price, image, description } = product
- Painel de administração: Adicionar atributo "cor".
- O código inclui automaticamente o novo campo.
- Código: const { name, price, image, description, color } = product
- Nenhum deployment necessário!
✨ Conceitos Chave
O que é um Atributo?
Um atributo é um único campo que armazena dados.
Exemplos:
- Nome do produto (string).
- Preço do produto (float).
- Imagem do produto (imagem).
- Data de publicação (data).
O que é um Conjunto de Atributos?
Um conjunto de atributos é uma coleção de atributos que define uma estrutura.
Exemplo: Conjunto de Atributos do Produto
- name (string)
- price (float)
- description (text)
- images (grupo de imagens)
- category (lista)
- inStock (inteiro)
Por que Usar Conjuntos de Atributos?
| ❌ Sem Attributes | ✅ Com Attributes |
|---|---|
| Campos codificados | Campos dinâmicos |
| Mudanças de código necessárias | Editar no painel de administração |
| Redeploy necessário | Atualizações ao vivo |
| Estrutura rígida | Estrutura flexível |
| Código duplicado | Conjuntos reutilizáveis |
📋 O que Você Precisa Saber
Três Termos Importantes
| Termo | O que é | Exemplo |
|---|---|---|
| Marker | Identificador de código único | "product_name" |
| Type | Que tipo de dado armazena | "string", "integer", "image" |
| Value | Valor do atributo | "Nome do Produto" |
Importante sobre Markers:
- Deve ser único
- Sem espaços (use
_em vez disso) - Não pode começar com um número
- Use letras minúsculas para consistência
Exemplos:
- ✅ Bom:
product_name,price_usd,main_image - ❌ Ruim:
product name,2nd_price,Product Name
📚 Tipos de Dados Disponíveis
Os atributos podem armazenar diferentes tipos de dados. Escolha o tipo certo para cada campo.
Tabela de Referência Rápida
| Tipo | Melhor Para | Uso Exemplo |
|---|---|---|
| string | Texto curto | Nome do produto, email |
| text | Texto longo formatado | Postagem de blog, descrição |
| textWithHeader | Texto com título | Seções de artigo |
| integer | Números inteiros | Quantidade, idade |
| real | Decimais de alta precisão | Dados científicos |
| float | Números decimais | Preço, avaliação |
| date | Apenas a data | Data de nascimento, prazo |
| dateTime | Data + hora | Início do evento, publicado em |
| time | Apenas a hora | Horário de funcionamento |
| file | Qualquer arquivo | PDF, documento |
| image | Imagem única | Avatar, logo |
| groupOfImages | Múltiplas imagens | Galeria de fotos |
| radioButton | Escolha única | Tamanho (P/M/G) |
| list | Seleção dropdown | País, categoria |
| entity | Link para outro conteúdo | Produtos relacionados |
| timeInterval | Intervalo de datas | Período de promoção |
| json | Dados estruturados personalizados | Resposta de API |
🔍 Descrições Detalhadas dos Tipos de Dados
Tipos de Texto
Quando usar o que:
- string - Linha única, menos de 255 caracteres (nome, email, título)
- text - Múltiplos parágrafos, suporta formatação (artigos, descrições)
- textWithHeader - Texto que precisa de um título (seções de blog, FAQs)
Tipos de Números
Quando usar o que:
- integer - Sem decimais necessários (idade, quantidade, visualizações)
- float - Decimais padrão (preço $19.99, avaliação 4.5)
- real - Precisão extra necessária (cálculos científicos)
Tipos de Data/Hora
Quando usar o que:
- date - Apenas o dia (aniversário, prazo)
- time - Apenas a hora (horário comercial, hora da consulta)
- dateTime - Ambos necessários (início do evento, artigo publicado)
- timeInterval - Período entre datas (duração da venda, datas de férias)
Tipos de Arquivo e Imagem
Quando usar o que:
- file - Qualquer documento (PDF, DOC, ZIP)
- image - Uma imagem (foto do produto, avatar)
- groupOfImages - Múltiplas imagens (galeria, imagens do produto)
Tipos de Seleção
Quando usar o que:
- radioButton - Escolher apenas UMA opção (Sim/Não, Tamanho P/M/G)
- list - Dropdown com opções (País, Categoria, Status)
Tipos Avançados
- entity - Link para outras páginas/produtos (Itens Relacionados, Categorias)
- json - Armazenar estruturas de dados complexas (respostas de API)
📖 Exemplos de Tipos de Dados
Abaixo estão exemplos técnicos da estrutura de cada tipo de dado.
💡 Os dados retornados no conjunto de atributos não incluem os valores reais dos atributos, pois esses valores estão contidos em entidades específicas, como páginas, produtos, etc. A única exceção é o tipo de atributo timeInterval. Este atributo pode ter valores verificando a caixa correspondente no painel de administração
Clique para ver todos os exemplos de tipos de dados
Referência de Tipos de Dados
Os tipos de dados podem ser dos seguintes tipos:
- String: Texto simples, por exemplo, "Olá, mundo!".
Exemplo:
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "Extra"
}
]
}
- Text: Texto mais longo, frequentemente formatado, por exemplo, um artigo ou uma carta.
Exemplo:
{
"type": "text",
"value": {},
"marker": "text",
"position": 2,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text"
},
"additionalFields": []
}
- Text with Header: Texto com um cabeçalho que pode ser usado para denotar um tópico ou categoria.
Exemplo:
{
"type": "textWithHeader",
"value": {},
"marker": "text_with_header",
"position": 3,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text With Header"
},
"additionalFields": []
}
- Integer: Um número inteiro, por exemplo, 5, 100, -2.
Exemplo:
{
"type": "integer",
"value": {},
"marker": "integer",
"position": 4,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Integer"
},
"additionalFields": []
}
- Real: O mesmo que Float, mas com maior precisão.
Exemplo:
{
"type": "real",
"value": {},
"marker": "real_number",
"position": 5,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Real Number"
},
"additionalFields": []
}
- Float: Um tipo de dado para números de ponto flutuante que podem ter uma parte decimal, por exemplo, 3.14, 1.5, -0.25.
Exemplo:
{
"type": "float",
"value": {},
"marker": "float",
"position": 6,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Float"
},
"additionalFields": []
}
- Date and Time: Uma combinação de data e hora, por exemplo, 2023-10-27 10:00:00.
Exemplo:
{
"type": "dateTime",
"value": {},
"marker": "date_time",
"position": 7,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "DateTime"
},
"additionalFields": []
}
- Date: Uma data, por exemplo, 2023-10-27.
Exemplo:
{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": []
}
- Time: Um horário, por exemplo, 10:00:00.
Exemplo:
{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": []
}
- File: Qualquer arquivo no seu computador, por exemplo, um documento, imagem, música.
Exemplo:
{
"type": "file",
"value": {},
"marker": "file",
"position": 10,
"listTitles": [],
"validators": {
"checkingFilesValidator": {
"maxUnits": "kb",
"maxValue": "2000",
"minUnits": "kb",
"minValue": 0,
"extensions": []
}
},
"localizeInfos": {
"title": "File"
},
"additionalFields": []
}
- Image: Uma imagem, por exemplo, uma fotografia, desenho.
Exemplo:
{
"type": "image",
"value": {},
"marker": "image",
"position": 11,
"listTitles": [],
"validators": {
"sizeInPixelsValidator": {
"maxX": "500",
"maxY": "500"
}
},
"localizeInfos": {
"title": "Image"
},
"additionalFields": []
}
- Group of Images: Uma coleção de imagens, por exemplo, um álbum de fotos.
Exemplo:
{
"type": "groupOfImages",
"value": {},
"marker": "image_group",
"position": 12,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Image Group"
},
"additionalFields": []
}
- Radio Button: Um botão de seleção do qual apenas uma opção pode ser escolhida.
Exemplo:
{
"type": "radioButton",
"value": {},
"marker": "radio",
"position": 13,
"listTitles": [
{
"title": "A",
"value": "a",
"extended": {
"type": null,
"value": null
},
"position": 1
},
{
"title": "B",
"value": "b",
"extended": {
"type": null,
"value": null
},
"position": 2
}
],
"validators": {},
"localizeInfos": {
"title": "Radio"
},
"additionalFields": []
}
- List: Uma lista de itens, por exemplo, uma lista de compras.
Exemplo:
{
"type": "list",
"value": {},
"marker": "list",
"position": 14,
"listTitles": [
{
"title": "A",
"value": "a",
"extended": {
"type": null,
"value": null
},
"position": 1
},
{
"title": "B",
"value": "b",
"extended": {
"type": null,
"value": null
},
"position": 2
},
{
"title": "C",
"value": "c",
"extended": {
"type": "string",
"value": "Valor Adicional"
},
"position": 3
}
],
"validators": {},
"localizeInfos": {
"title": "List"
},
"additionalFields": []
}
- Entity: Uma entidade representando um objeto.
Exemplo:
{
"type": "entity",
"value": {},
"marker": "entity",
"position": 15,
"listTitles": [
{
"title": "Produtos",
"value": {
"id": 1,
"depth": 0,
"parentId": null,
"position": 1,
"selected": true
}
},
{
"title": "Página Normal",
"value": {
"id": 4,
"depth": 0,
"parentId": null,
"position": 2,
"selected": true
}
},
{
"title": "Erro",
"value": {
"id": 2,
"depth": 0,
"parentId": null,
"position": 3,
"selected": true
}
}
],
"validators": {},
"localizeInfos": {
"title": "Entity"
},
"additionalFields": [
{
"type": "string",
"value": "Campo de Teste",
"marker": "test_field"
}
]
}
- Time interval: Um calendário flexível com uma interface amigável para gerenciar dados de intervalo de tempo.
Exemplo:
{
"time_interval": {
"id": 4,
"type": "timeInterval",
"value": [
// Array de grupos de valores, cada um vinculado a um intervalo específico (via intervalId). Este array é formado quando Receber valores é habilitado no CMS
{
// Registros de tempo específicos aplicáveis às datas especificadas
"values": [
{
// Identificador único do registro
"id": "1dc1787d-acc3-4315-a45d-52166c72e577",
// Intervalo de datas (inclusivo) ao qual este registro se aplica
"dates": ["2025-11-27T00:00:00.000Z", "2025-11-27T00:00:00.000Z"],
// Array de intervalos de tempo no formato [[início, fim], ...]
"times": [
[
// Início do intervalo de tempo (horas e minutos)
{
"hours": 19,
"minutes": 18
},
// Fim do intervalo de tempo
{
"hours": 21,
"minutes": 19
}
]
],
// Reservado (não utilizado na implementação atual)
"intervals": [],
// Exceções — segmentos de tempo excluídos da programação na data especificada
"exceptions": [
{
// Data da exceção
"date": "2025-12-17T17:00:00.000Z",
// Array de segmentos de tempo excluídos
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
// Referência ao intervalo do array `intervals`
"intervalId": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6",
// Flag para recorrência semanal (no dia correspondente da semana)
"inEveryWeek": true
},
{
"id": "cfa187d3-0284-4e0d-8206-7b353cf47110",
"dates": ["2025-12-18T00:00:00.000Z", "2025-12-18T00:00:00.000Z"],
// Array de intervalos de tempo no formato [[início, fim], ...]
"times": [
[
{
"hours": 0,
"minutes": 25
},
{
"hours": 0,
"minutes": 27
}
],
[
{
"hours": 19,
"minutes": 18
},
{
"hours": 21,
"minutes": 19
}
]
],
"intervals": [],
"exceptions": [
{
"date": "2025-12-17T17:00:00.000Z",
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
"intervalId": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6"
},
{
"id": "474de0f7-595f-49a5-aaa7-65617203ae69",
"dates": ["2025-12-25T00:00:00.000Z", "2025-12-25T00:00:00.000Z"],
// Sem intervalos de tempo
"times": [],
// Regras dinâmicas para expansão da programação
"external": [
{
// Data base para calcular o evento recorrente
"date": "2026-01-15T00:00:00.000Z",
// O evento se repete todo mês neste dia
"inEveryMonth": true
}
],
"intervals": [],
"exceptions": [
{
"date": "2025-12-17T17:00:00.000Z",
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
"intervalId": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6",
// Flag para recorrência semanal
"inEveryWeek": true,
// Flag para recorrência mensal
"inEveryMonth": true,
// Flag para recorrência anual
"inEveryYears": true
}
],
// Referência ao intervalo do array `intervals`
"intervalId": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6"
},
{
"values": [
{
"id": "2f80dc18-16da-45cb-82c6-e41e1f6ee084",
"dates": ["2025-12-22T00:00:00.000Z", "2025-12-23T00:00:00.000Z"],
"times": [],
"intervals": [],
"exceptions": [],
"intervalId": "918175fd-cc18-4ca5-9bee-c78c61c9415a",
"inEveryWeek": true,
"inEveryMonth": true
}
],
"intervalId": "918175fd-cc18-4ca5-9bee-c78c61c9415a"
}
],
"isPrice": false,
"original": true,
"intervals": [
// Array de modelos de intervalo de tempo
{
// Identificador único do modelo de intervalo
"id": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6",
"range": [
// Intervalo principal de aplicabilidade do intervalo
"2025-11-26T17:00:00.000Z",
"2025-11-26T17:00:00.000Z"
],
// Exceções no nível de todo o intervalo
"external": [
{
"date": "2025-12-17T17:00:00.000Z",
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
// Intervalos de tempo internos (períodos de trabalho/atividade)
"intervals": [
{
"id": "01fea594-9933-47ac-af0a-ec0e0884f618",
// Fim do intervalo de tempo
"end": {
"hours": 21,
"minutes": 19
},
// Início do intervalo de tempo
"start": {
"hours": 19,
"minutes": 18
},
// Duração do bloco repetido (em minutos); null — sem periodicidade
"period": null
},
{
"id": "22ba24af-1fae-4422-8c92-0635b684a306",
"end": {
"hours": 0,
"minutes": 29
},
"start": {
"hours": 0,
"minutes": 25
},
// Periodicidade: os intervalos de tempo se repetem com um passo de 2 minutos
"period": 2,
// Exceção dentro do intervalo periódico
"external": {
// Flag para exibir a exceção na interface
"show": false,
// Duração do fragmento excluído (em minutos)
"value": 2
}
}
],
"inEveryWeek": true,
"inEveryMonth": true,
"inEveryYears": true
},
{
"id": "918175fd-cc18-4ca5-9bee-c78c61c9415a",
"range": ["2026-01-18T17:00:00.000Z", "2026-01-20T17:00:00.000Z"],
// Sem exceções
"external": [],
// Sem intervalos de tempo internos
"intervals": [],
"inEveryWeek": true,
"inEveryMonth": true,
"inEveryYears": true
}
],
// Flag para visibilidade do atributo na interface
"isVisible": true,
"identifier": "time_interval",
"localizeInfos": {
"en_US": {
"title": "Time interval"
}
},
"receiveValues": true
}
}
- JSON: Alguns dados em formato JSON.
Exemplo:
{
"type": "json",
"value": {},
"marker": "json",
"position": 17,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Json"
},
"additionalFields": []
}
A interface de preenchimento de conteúdo corresponderá ao tipo de dado selecionado para cada campo de atributo.
💡 Notas Importantes
Validadores
Você pode adicionar validadores para atributos para garantir a qualidade dos dados:
- Campos obrigatórios.
- Comprimento mínimo/máximo para texto.
- Limites de tamanho de arquivo para uploads.
- Dimensões em pixels para imagens.
- Intervalos de datas.
Clique para ver exemplos de validadores
- requiredValidator: Exige que um valor seja inserido.
Exemplo:
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "Currency"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "extra"
}
]
}
- defaultValueValidator:
Exemplo:
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"defaultValueValidator": {
"customErrorText": "Erro personalizado",
"fieldDefaultValue": "usd",
"fieldDefaultValue2": "",
},
},
"localizeInfos": {
"title": "String"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "extra"
}
]
}
Saiba mais: Veja a seção Validadores para configuração detalhada.
Conjuntos de Atributos Compartilhados
⚠️ Importante: Se um conjunto de atributos é usado por várias entidades, tenha cuidado ao fazer alterações:
Adicionando um atributo:
- Ele será adicionado a todas as entidades que usam o conjunto.
- O conteúdo existente permanece inalterado.
- O novo campo ficará vazio para itens existentes.
Removendo um atributo:
- Ele será removido de todas as entidades que usam o conjunto.
- Os valores existentes serão excluídos permanentemente.
Exemplo:
Conjunto de atributos "Informações do Produto" usado por:
- Produtos Físicos
- Produtos Digitais
- Serviços
Adicionando o atributo "peso" → Adicionado a TODOS os três!
Removendo o atributo "peso" → Removido de TODOS os três! ⚠️
📊 Tabela de Referência Rápida - Métodos Comuns
| Método | O que faz |
|---|---|
| getAttributes() | Obtendo todos os objetos de conjuntos de atributos. |
| getAttributesByMarker() | Obtendo todos os atributos por marcador com dados do conjunto de atributos. |
| getAttributeSetByMarker() | Obtendo um único objeto de conjunto de atributos por marcador. |
| getSingleAttributeByMarkerSet() | Obtendo um atributo com dados do conjunto de atributos. |
❓ Perguntas Comuns (FAQ)
Qual é a diferença entre string e text?
- string - Texto curto, linha única (máx ~255 caracteres). Use para nomes, títulos, emails.
- text - Texto longo, múltiplos parágrafos, suporta formatação e HTML. Use para descrições, artigos.
Quando devo usar integer vs float?
- integer - Apenas números inteiros:
1, 2, 100, -5. Use para quantidades, contagens, idades. - float - Números decimais:
19.99, 4.5, -0.25. Use para preços, avaliações, medições. - real - Como float, mas com maior precisão. Use para cálculos científicos.
Melhor prática: Planeje seus tipos de atributos antes de adicionar conteúdo.
O que acontece se eu excluir um atributo?
- Você não pode excluir um atributo se ele estiver sendo usado em um conjunto de atributos.
Posso reutilizar o mesmo atributo em diferentes conjuntos de atributos?
Não, cada atributo pertence a um conjunto de atributos. Mas você pode:
- Criar atributos semelhantes com marcadores diferentes
- Reutilizar conjuntos de atributos inteiros em várias entidades
O que é o "marker" e por que é importante?
O marker é o identificador técnico que você usa no código:
// No seu código:
product.attributeValues.product_name // ← "product_name" é o marker
// VS o nome (exibido na administração):
"Nome do Produto" // ← Isso é apenas para humanos
Regras para markers:
- Deve ser único
- Sem espaços (use
_) - Não pode começar com números
- Use letras minúsculas
- Escolha nomes descritivos
Como sei qual tipo usar para meus dados?
Pergunte a si mesmo:
-
É texto?
- Curto (< 255 caracteres)? →
string - Longo com formatação? →
text - Precisa de um título? →
textWithHeader
- Curto (< 255 caracteres)? →
-
É um número?
- Sem decimais? →
integer - Tem decimais? →
float - Precisão científica? →
real
- Sem decimais? →
-
É uma escolha?
- Escolher uma opção? →
radioButton - Menu dropdown? →
list
- Escolher uma opção? →
-
É um arquivo?
- Imagem? →
imageougroupOfImages - Documento? →
file
- Imagem? →
-
É uma data?
- Apenas data? →
date - Data + hora? →
dateTime - Período de tempo? →
timeInterval
- Apenas data? →
Posso ter atributos aninhados (atributos dentro de atributos)?
Sim, você pode usar Campos Adicionais
Como adiciono regras de validação?
No painel de administração do OneEntry:
- Vá para seu conjunto de atributos
- Clique em um atributo
- Adicione validadores (obrigatório, min/max, regex, etc.)
- Salve as alterações
Saiba mais: Veja a seção Validadores para configuração detalhada.
🎓 Melhores Práticas
- Use marcadores descritivos (
product_priceem vez depp) - Planeje os tipos de atributos antes de adicionar conteúdo
- Reutilize conjuntos de atributos quando possível
- Adicione validadores para garantir a qualidade dos dados
- Documente para que cada atributo serve
Mais informações sobre a interface do usuário do módulo https://doc.oneentry.cloud/docs/attributes/introduction
Definição do módulo AttributesSets
const { AttributesSets } = defineOneEntry( "sua-url-do-projeto", { "token": "seu-token-de-aplicativo" });
🔗 Documentação Relacionada
- Módulo de Produtos - Usa conjuntos de atributos para dados de produtos
- Módulo de Páginas - Usa conjuntos de atributos para conteúdo de páginas
- Módulo de Blocos - Usa conjuntos de atributos para blocos reutilizáveis
- Módulo de Formulários - Crie formulários com campos personalizados