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.
- Mudar 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, price, image, description }
- Para adicionar o campo "cor" → Mudar o código, redeploy, esperar.
Com Attributes (dinâmico):
- Painel de administração: Adicione o atributo "cor".
- O código inclui automaticamente o novo campo.
- 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
| Term | 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:
- Devem ser únicos
- Sem espaços permitidos (use
_em vez disso) - Não podem 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
Reutilização
Conjuntos de atributos podem ser reutilizados em diferentes entidades:
Conjunto de Atributos "Informações Básicas":
- title (string)
- description (text)
- publish_date (date)
Usado por:
- Postagens de blog
- Artigos de notícias
- Páginas de produtos
- Listagens de eventos
Por que isso importa: Mude uma vez, atualizações em todos os lugares!
📚 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 em 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 do compromisso)
- 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, configurações)
📖 Exemplos de Tipos de Dados
Abaixo estão exemplos técnicos da estrutura de cada tipo de dado.
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 templates de intervalo de tempo
{
// Identificador único do template 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 intervalo inteiro
"external": [
{
"date": "2025-12-17T17:00:00.000Z",
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
// Intervalos internos (períodos de trabalho/ativos)
"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.
Saiba mais: Veja a seção "Validadores" para configuração detalhada.
Conjuntos de Atributos Compartilhados
⚠️ Importante: Se um conjunto de atributos for usado por várias entidades, tenha cuidado ao fazer alterações:
Excluindo um atributo:
- Remove-o em todos os lugares onde o conjunto é usado.
- Exclui todo o conteúdo nesse campo.
- Não pode ser desfeito!
Adicionando um atributo:
- Adicionado em todos os lugares onde o conjunto é usado.
- Conteúdo existente inalterado.
- Novo campo ficará vazio para itens existentes.
Exemplo:
"Informações do Produto" usado por:
- Produtos Físicos.
- Produtos Digitais.
- Serviços.
Excluir o atributo "peso" → Removido de TODOS os três! ⚠️
📊 Tabela de Referência Rápida - Métodos Comuns
| Método | O que faz | Quando usar |
|---|---|---|
| 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 atributo 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:
- Devem ser únicos
- Sem espaços (use
_) - Não podem começar com números
- Use letras minúsculas
- Escolha nomes descritivos
Como eu 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)?
Não diretamente, mas você pode usar:
- Tipo entity para vincular a outros conteúdos
- Tipo json para armazenar dados estruturados
- Múltiplos conjuntos de atributos para organizar campos relacionados
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
Validadores comuns:
- Campo obrigatório
- Comprimento mínimo/máximo
- Formato de email
- Formato de URL
- Limites de tamanho de arquivo
- Dimensões de imagem
🎓 Melhores Práticas
- Use marcadores descritivos (
product_priceem vez depp) - Planeje os tipos de atributo antes de adicionar conteúdo
- Reutilize conjuntos de atributos sempre que 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ágina
- Módulo de Blocos - Usa conjuntos de atributos para blocos reutilizáveis
- Módulo de Formulários - Crie formulários com campos personalizados