Pular para o conteúdo principal

Introdução

Defina campos personalizados para seu conteúdo sem tocar no código.

Mais informações sobre a interface do usuário do módulo https://doc.oneentry.cloud/docs/category/attributes


🎯 O que este módulo faz?

O módulo AttributesSets permite que você leia as definições de campos personalizados (conjuntos de atributos) usados pelo seu conteúdo - produtos, páginas, formulários, blocos e mais. Um conjunto de atributos é o esquema que descreve quais campos uma entidade possui e qual tipo cada campo é; você define isso no painel de administração do OneEntry e busca sua estrutura com este módulo.

Nota: conjuntos de atributos descrevem o esquema, não os valores. Os valores reais estão nas próprias entidades (uma página, produto, etc.) sob seus attributeValues. A única exceção é o tipo timeInterval, que pode carregar valores - veja os exemplos abaixo.

🚀 Início Rápido

Inicialize o módulo a partir de defineOneEntry:


const { AttributesSets } = defineOneEntry(
"your-project-url", {
"token": "your-app-token"
}
);

Busque os atributos definidos em um conjunto e leia seus marcadores e tipos:

// Get every attribute in the "productAttributes" set.
const attributes = await AttributesSets.getAttributesByMarker(
"productAttributes",
"en_US",
);

attributes.forEach((attr) => {
console.log(attr.marker, attr.type, attr.localizeInfos.title);
});

✨ Conceitos Chave

Atributo, Conjunto de Atributos, Valor

TermoO que éExemplo
AtributoUma definição de campo único (um marcador + um tipo)preço (float)
Conjunto de AtributosUma coleção de atributos - o esquema da entidadeconjunto "Produto"
ValorOs dados que uma entidade armazena para um atributo19.99 em um produto específico

Um conjunto de atributos agrupa atributos em um esquema reutilizável. O mesmo conjunto pode ser anexado a várias entidades, então mudar o conjunto altera os campos disponíveis em todos os lugares onde é usado.

Marcadores

O marcador é o identificador técnico que você usa no código (por exemplo, product_name). Ele mapeia para o título legível por humanos exibido no painel de administração.

product.attributeValues.product_name; // "product_name" is the marker

Regras de Marcador:

  • Deve ser único
  • Sem espaços (use _)
  • Não pode começar com um número
  • Use letras minúsculas para consistência

✅ Bom: product_name, price_usd, main_image — ❌ Ruim: product name, 2nd_price, Product Name

📋 O que você precisa saber

Conjuntos de atributos compartilhados

Se um conjunto de atributos é usado por várias entidades, as mudanças se propagam para todas elas:

  • Adicionando um atributo - ele aparece em cada entidade que usa o conjunto; o conteúdo existente mantém seus valores e o novo campo começa vazio.
  • Removendo um atributo - ele é removido de cada entidade que usa o conjunto, e os valores existentes são permanentemente excluídos.

Você não pode excluir um atributo enquanto ele ainda estiver sendo usado em um conjunto de atributos.

Validadores

Os atributos podem carregar validadores para garantir a qualidade dos dados - campos obrigatórios, limites de comprimento mínimo/máximo, limites de tamanho de arquivo, dimensões de pixels de imagem, intervalos de datas e um valor padrão. A configuração do validador é retornada em cada atributo sob validators.

Clique para ver exemplos de validadores
  • requiredValidator: exige que um valor seja inserido.
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "Currency"
},
"additionalFields": {
"extra": {
"type": "integer",
"value": "10",
"marker": "extra"
}
}
}

  • defaultValueValidator: fornece um valor padrão para o campo.
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"defaultValueValidator": {
"customErrorText": "Custom error",
"fieldDefaultValue": "usd",
"fieldDefaultValue2": ""
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": {
"extra": {
"type": "integer",
"value": "10",
"marker": "extra"
}
}
}

Saiba mais: Veja Validadores para configuração detalhada.

Atributos Aninhados

Você pode anexar campos extras a um atributo via Campos Adicionais (retornados sob additionalFields).


📊 Tabela de Referência Rápida - Métodos Comuns

MétodoO que faz
getAttributes()Obtém todos os objetos de conjunto de atributos.
getAttributesByMarker()Obtém todos os atributos de um conjunto, com dados do conjunto de atributos.
getAttributeSetByMarker()Obtém um único objeto de conjunto de atributos por marcador.
getSingleAttributeByMarkerSet()Obtém um atributo (com dados do conjunto) por marcador de conjunto e marcador de atributo.

📚 Tipos de Dados Disponíveis

Cada atributo tem um type. Escolha o tipo certo para cada campo.

TipoMelhor ParaExemplo de Uso
stringTexto curto (< 255 caracteres)Nome do produto, e-mail
textTexto longo formatadoPostagem de blog, descrição
textWithHeaderTexto com um títuloSeções de artigo
integerNúmeros inteirosQuantidade, idade
realDecimais de alta precisãoDados científicos
floatNúmeros decimaisPreço, avaliação
dateApenas a dataData de nascimento, prazo
dateTimeData + horaInício do evento, publicado em
timeApenas a horaHorário de funcionamento
fileQualquer arquivoPDF, documento
imageImagem únicaAvatar, logotipo
groupOfImagesMúltiplas imagensGaleria de fotos
radioButtonEscolha únicaTamanho (P/M/G)
listSeleção em dropdownPaís, categoria
buttonAção interativaEnviar formulário, CTA
spamProteção contra spam em formuláriosCampo honeypot anti-bot
entityLink para outro conteúdoProdutos relacionados
timeIntervalIntervalos de data/horaHorários, período de promoção

Escolhendo um tipo

  • Texto: string (linha única), text (parágrafos formatados), textWithHeader (texto com um título).
  • Números: integer (sem decimais), float (decimais padrão), real (precisão extra).
  • Data/hora: date, time, dateTime, ou timeInterval (intervalos/horários).
  • Arquivos/imagens: file (qualquer documento), image (uma imagem), groupOfImages (uma galeria).
  • Escolhas: radioButton (escolha uma), list (dropdown).
  • Avançado: entity (link para outras páginas/produtos), button (ação interativa), spam (proteção contra bots).

📖 Exemplos de Tipos de Dados

Abaixo estão exemplos técnicos da estrutura de cada tipo de dado conforme retornado pela API.

💡 Os dados retornados no conjunto de atributos não incluem os valores reais dos atributos - esses estão em entidades específicas (páginas, produtos, etc.). A única exceção é timeInterval, que pode carregar valores quando a caixa correspondente está marcada no painel de administração.

Clique para ver todos os exemplos de tipos de dados

Referência de Tipos de Dados

  • String: Texto simples, por exemplo, "Olá, mundo!".
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": {
"Extra": {
"type": "integer",
"value": "10",
"marker": "Extra"
}
}
}

  • Texto: Texto mais longo, frequentemente formatado, por exemplo, um artigo ou uma carta.
{
"type": "text",
"value": {},
"marker": "text",
"position": 2,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text"
},
"additionalFields": {}
}

  • Texto com Cabeçalho: Texto com um cabeçalho que pode ser usado para denotar um tópico ou categoria.
{
"type": "textWithHeader",
"value": {},
"marker": "text_with_header",
"position": 3,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text With Header"
},
"additionalFields": {}
}

  • Inteiro: Um número inteiro, por exemplo, 5, 100, -2.
{
"type": "integer",
"value": {},
"marker": "integer",
"position": 4,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Integer"
},
"additionalFields": {}
}

  • Real: O mesmo que Float, mas com maior precisão.
{
"type": "real",
"value": {},
"marker": "real_number",
"position": 5,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Real Number"
},
"additionalFields": {}
}

  • Float: Um número de ponto flutuante que pode ter uma parte decimal, por exemplo, 3.14, 1.5, -0.25.
{
"type": "float",
"value": {},
"marker": "float",
"position": 6,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Float"
},
"additionalFields": {}
}

  • Data e Hora: Uma combinação de data e hora, por exemplo, 2023-10-27 10:00:00.
{
"type": "dateTime",
"value": {},
"marker": "date_time",
"position": 7,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "DateTime"
},
"additionalFields": {}
}

  • Data: Uma data, por exemplo, 2023-10-27.
{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": {}
}

  • Hora: Uma hora, por exemplo, 10:00:00.
{
"type": "time",
"value": {},
"marker": "time",
"position": 9,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Time"
},
"additionalFields": {}
}

  • Arquivo: Qualquer arquivo, por exemplo, um documento, imagem, música.
{
"type": "file",
"value": {},
"marker": "file",
"position": 10,
"listTitles": [],
"validators": {
"checkingFilesValidator": {
"maxUnits": "kb",
"maxValue": "2000",
"minUnits": "kb",
"minValue": 0,
"extensions": []
}
},
"localizeInfos": {
"title": "File"
},
"additionalFields": {}
}

  • Imagem: Uma imagem, por exemplo, uma fotografia ou desenho.
{
"type": "image",
"value": {},
"marker": "image",
"position": 11,
"listTitles": [],
"validators": {
"sizeInPixelsValidator": {
"maxX": "500",
"maxY": "500"
}
},
"localizeInfos": {
"title": "Image"
},
"additionalFields": {}
}

  • Grupo de Imagens: Uma coleção de imagens, por exemplo, um álbum de fotos.
{
"type": "groupOfImages",
"value": {},
"marker": "image_group",
"position": 12,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Image Group"
},
"additionalFields": {}
}

  • Botão de Rádio: Uma seleção da qual apenas uma opção pode ser escolhida.
{
"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": {}
}

  • Lista: Uma lista de itens selecionáveis, por exemplo, um dropdown.
{
"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": "Additional Value"
},
"position": 3
}
],
"validators": {},
"localizeInfos": {
"title": "List"
},
"additionalFields": {}
}

  • Entidade: Um link para outro objeto (página, produto, …).
{
"type": "entity",
"value": {},
"marker": "entity",
"position": 15,
"listTitles": [
{
"title": "Products",
"value": {
"id": 1,
"depth": 0,
"parentId": null,
"isPinned": false,
"position": 1,
"selected": true
}
},
{
"title": "Normal Page",
"value": {
"id": 4,
"depth": 0,
"parentId": null,
"isPinned": false,
"position": 2,
"selected": true
}
},
{
"title": "Error",
"value": {
"id": 2,
"depth": 0,
"parentId": null,
"isPinned": false,
"position": 3,
"selected": true
}
}
],
"validators": {},
"localizeInfos": {
"title": "Entity"
},
"additionalFields": {
"test_field": {
"type": "string",
"value": "Test Field",
"marker": "test_field"
}
}
}

  • Intervalo de tempo: Um calendário flexível com uma interface amigável para gerenciar dados de intervalo de tempo.
{
"time_interval": {
"id": 4,
"type": "timeInterval",
"value": [
// Array of value groups, each linked to a specific interval (via intervalId). This array is formed when Receive values is enabled in CMS
{
// Specific time records applicable to the specified dates
"values": [
{
// Unique record identifier
"id": "1dc1787d-acc3-4315-a45d-52166c72e577",
// Date range (inclusive) to which this record applies
"dates": ["2025-11-27T00:00:00.000Z", "2025-11-27T00:00:00.000Z"],
// Array of time slots in format [[start, end], ...]
"times": [
[
// Start of time slot (hours and minutes)
{
"hours": 19,
"minutes": 18
},
// End of time slot
{
"hours": 21,
"minutes": 19
}
]
],
// Reserved (not used in current implementation)
"intervals": [],
// Exceptions — time segments excluded from the schedule on the specified date
"exceptions": [
{
// Exception date
"date": "2025-12-17T17:00:00.000Z",
// Array of excluded time segments
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
// Reference to interval from the `intervals` array
"intervalId": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6",
// Flag for weekly recurrence (on the corresponding day of the week)
"inEveryWeek": true
},
{
"id": "cfa187d3-0284-4e0d-8206-7b353cf47110",
"dates": ["2025-12-18T00:00:00.000Z", "2025-12-18T00:00:00.000Z"],
// Array of time slots in format [[start, end], ...]
"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"],
// No time slots
"times": [],
// Dynamic rules for schedule expansion
"external": [
{
// Base date for calculating recurring event
"date": "2026-01-15T00:00:00.000Z",
// Event repeats every month on this day
"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 for weekly recurrence
"inEveryWeek": true,
// Flag for monthly recurrence
"inEveryMonth": true,
// Flag for yearly recurrence
"inEveryYears": true
}
],
// Reference to interval from the `intervals` array
"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 of time interval templates
{
// Unique identifier of interval template
"id": "0da61a19-49cb-40b1-88e6-1fa3c93a1fa6",
"range": [
// Main range of interval applicability
"2025-11-26T17:00:00.000Z",
"2025-11-26T17:00:00.000Z"
],
// Exceptions at the entire interval level
"external": [
{
"date": "2025-12-17T17:00:00.000Z",
"externalTimes": [
["2025-12-17T17:25:00.000Z", "2025-12-17T17:27:00.000Z"]
]
}
],
// Internal time slots (working/active periods)
"intervals": [
{
"id": "01fea594-9933-47ac-af0a-ec0e0884f618",
// End of time slot
"end": {
"hours": 21,
"minutes": 19
},
// Start of time slot
"start": {
"hours": 19,
"minutes": 18
},
// Duration of repeating block (in minutes); null — no periodicity
"period": null
},
{
"id": "22ba24af-1fae-4422-8c92-0635b684a306",
"end": {
"hours": 0,
"minutes": 29
},
"start": {
"hours": 0,
"minutes": 25
},
// Periodicity: time slots repeat with 2-minute step
"period": 2,
// Exception inside periodic slot
"external": {
// Flag for displaying exception in the interface
"show": false,
// Duration of excluded fragment (in minutes)
"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"],
// No exceptions
"external": [],
// No internal time slots
"intervals": [],
"inEveryWeek": true,
"inEveryMonth": true,
"inEveryYears": true
}
],
// Flag for attribute visibility in the interface
"isVisible": true,
"identifier": "time_interval",
"localizeInfos": {
"title": "Time interval"
},
"receiveValues": true
}
}

A interface de preenchimento de conteúdo no painel de administração corresponde ao tipo de dado selecionado para cada campo de atributo.


❓ 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, e-mails.
  • text - texto longo, múltiplos parágrafos, suporta formatação e HTML. Use para descrições, artigos.

Quando devo usar integer, float ou real?

  • integer - apenas números inteiros (1, 2, 100, -5). Use para quantidades, contagens, idades.
  • float - números decimais (19.99, 4.5). Use para preços, avaliações, medições.
  • real - como float, mas com maior precisão. Use para cálculos científicos.

Posso reutilizar o mesmo atributo em diferentes conjuntos de atributos?

Os atributos são definidos dentro do esquema de um conjunto de atributos (por marcador). Para reutilizar um campo em outro lugar, crie atributos semelhantes com marcadores diferentes ou reutilize todo o conjunto de atributos em várias entidades.


O que é o "marcador" e por que é importante?

O marcador é o identificador técnico que você usa no código (por exemplo, product.attributeValues.product_name), em contraste com o título legível por humanos exibido no painel de administração. Os marcadores devem ser únicos, não conter espaços (use _), não começar com um número e são convencionalmente em letras minúsculas.


Posso ter atributos aninhados?

Sim - use Campos Adicionais (retornados sob additionalFields).


Como adiciono regras de validação?

No painel de administração do OneEntry: abra seu conjunto de atributos, clique em um atributo, adicione validadores (obrigatório, min/max, etc.) e salve. Saiba mais: Validadores.


🎓 Melhores Práticas

  • Use marcadores descritivos (product_price, não pp).
  • Planeje os tipos de atributos antes de adicionar conteúdo.
  • Reutilize conjuntos de atributos entre entidades sempre que possível.
  • Adicione validadores para garantir a qualidade dos dados.
  • Lembre-se de que conjuntos compartilhados propagam mudanças para cada entidade que os utiliza.

🔗 Documentação Relacionada