Saltar al contenido principal

Introducción

Define campos personalizados para tu contenido sin tocar el código.

Más información sobre la interfaz de usuario del módulo https://doc.oneentry.cloud/docs/category/attributes


🎯 ¿Qué hace este módulo?

El módulo AttributesSets te permite leer las definiciones de campos personalizados (conjuntos de atributos) utilizados por tu contenido: productos, páginas, formularios, bloques y más. Un conjunto de atributos es el esquema que describe qué campos tiene una entidad y qué tipo es cada campo; los defines en el panel de administración de OneEntry y obtienes su estructura con este módulo.

Nota: los conjuntos de atributos describen el esquema, no los valores. Los valores reales residen en las propias entidades (una página, un producto, etc.) bajo sus attributeValues. La única excepción es el tipo timeInterval, que puede llevar valores; consulta los ejemplos a continuación.

🚀 Inicio Rápido

Inicializa el módulo desde defineOneEntry:


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

Obtén los atributos definidos en un conjunto y lee sus marcadores y 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);
});

✨ Conceptos Clave

Atributo, Conjunto de Atributos, Valor

TérminoQué EsEjemplo
AtributoUna definición de campo único (un marcador + un tipo)precio (float)
Conjunto de AtributosUna colección de atributos - el esquema de la entidadconjunto "Producto"
ValorLos datos que una entidad almacena para un atributo19.99 en un producto específico

Un conjunto de atributos agrupa atributos en un esquema reutilizable. El mismo conjunto puede estar adjunto a múltiples entidades, por lo que cambiar el conjunto cambia los campos disponibles en todas partes donde se utiliza.

Marcadores

El marcador es el identificador técnico que usas en el código (por ejemplo, product_name). Se mapea al título legible por humanos que se muestra en el panel de administración.

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

Reglas de Marcador:

  • Debe ser único
  • Sin espacios (usa _)
  • No puede comenzar con un número
  • Usa minúsculas para consistencia

✅ Bueno: product_name, price_usd, main_image — ❌ Malo: product name, 2nd_price, Product Name

📋 Lo Que Necesitas Saber

Conjuntos de atributos compartidos

Si un conjunto de atributos es utilizado por múltiples entidades, los cambios se propagan a todas ellas:

  • Agregar un atributo - aparece en cada entidad que utiliza el conjunto; el contenido existente mantiene sus valores y el nuevo campo comienza vacío.
  • Eliminar un atributo - se elimina de cada entidad que utiliza el conjunto, y los valores existentes se eliminan permanentemente.

No puedes eliminar un atributo mientras aún se utiliza en un conjunto de atributos.

Validadores

Los atributos pueden llevar validadores para hacer cumplir la calidad de los datos: campos requeridos, longitud mínima/máxima, límites de tamaño de archivo, dimensiones de píxeles de imagen, rangos de fechas y un valor predeterminado. La configuración del validador se devuelve en cada atributo bajo validators.

Haz clic para ver ejemplos de validadores
  • requiredValidator: requiere que se ingrese un valor.
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "Currency"
},
"additionalFields": {
"extra": {
"type": "integer",
"value": "10",
"marker": "extra"
}
}
}

  • defaultValueValidator: proporciona un valor predeterminado para el 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"
}
}
}

Aprende más: Consulta Validadores para una configuración detallada.

Atributos anidados

Puedes adjuntar campos adicionales a un atributo a través de Campos Adicionales (devueltos bajo additionalFields).


📊 Tabla de Referencia Rápida - Métodos Comunes

MétodoQué Hace
getAttributes()Obtiene todos los objetos de conjunto de atributos.
getAttributesByMarker()Obtiene todos los atributos de un conjunto, con datos del conjunto de atributos.
getAttributeSetByMarker()Obtiene un solo objeto de conjunto de atributos por marcador.
getSingleAttributeByMarkerSet()Obtiene un atributo (con datos del conjunto) por marcador de conjunto y marcador de atributo.

📚 Tipos de Datos Disponibles

Cada atributo tiene un type. Elige el tipo correcto para cada campo.

TipoMejor ParaEjemplo de Uso
stringTexto corto (< 255 caracteres)Nombre del producto, correo electrónico
textTexto largo formateadoPublicación de blog, descripción
textWithHeaderTexto con un títuloSecciones de artículo
integerNúmeros enterosCantidad, edad
realDecimales de alta precisiónDatos científicos
floatNúmeros decimalesPrecio, calificación
dateSolo la fechaFecha de nacimiento, fecha límite
dateTimeFecha + horaInicio del evento, publicado en
timeSolo la horaHorarios de apertura
fileCualquier archivoPDF, documento
imageImagen únicaAvatar, logo
groupOfImagesMúltiples imágenesGalería de fotos
radioButtonOpción únicaTamaño (S/M/L)
listSelección desplegablePaís, categoría
buttonAcción interactivaEnviar formulario, CTA
spamProtección contra spam en formulariosCampo de honeypot anti-bot
entityEnlace a otro contenidoProductos relacionados
timeIntervalRangos de fecha/horaHorarios, período de promoción

Elegir un tipo

  • Texto: string (una línea), text (párrafos formateados), textWithHeader (texto con un encabezado).
  • Números: integer (sin decimales), float (decimales estándar), real (precisión extra).
  • Fecha/hora: date, time, dateTime, o timeInterval (rangos/horarios).
  • Archivos/imágenes: file (cualquier documento), image (una imagen), groupOfImages (una galería).
  • Opciones: radioButton (elige uno), list (desplegable).
  • Avanzado: entity (enlace a otras páginas/productos), button (acción interactiva), spam (protección contra bots).

📖 Ejemplos de Tipos de Datos

A continuación se presentan ejemplos técnicos de la estructura de cada tipo de dato tal como los devuelve la API.

💡 Los datos devueltos en el conjunto de atributos no incluyen los valores reales de los atributos; esos residen en entidades específicas (páginas, productos, etc.). La única excepción es timeInterval, que puede llevar valores cuando la casilla correspondiente está marcada en el panel de administración.

Haz clic para ver todos los ejemplos de tipos de datos

Referencia de Tipos de Datos

  • String: Texto simple, por ejemplo, "¡Hola, mundo!".
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": {
"Extra": {
"type": "integer",
"value": "10",
"marker": "Extra"
}
}
}

  • Text: Texto más largo, a menudo formateado, por ejemplo, un artículo o una carta.
{
"type": "text",
"value": {},
"marker": "text",
"position": 2,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text"
},
"additionalFields": {}
}

  • Text con Encabezado: Texto con un encabezado que puede usarse para denotar un tema o categoría.
{
"type": "textWithHeader",
"value": {},
"marker": "text_with_header",
"position": 3,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text With Header"
},
"additionalFields": {}
}

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

  • Real: Lo mismo que Float, pero con mayor precisión.
{
"type": "real",
"value": {},
"marker": "real_number",
"position": 5,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Real Number"
},
"additionalFields": {}
}

  • Float: Un número de punto flotante que puede tener una parte decimal, por ejemplo, 3.14, 1.5, -0.25.
{
"type": "float",
"value": {},
"marker": "float",
"position": 6,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Float"
},
"additionalFields": {}
}

  • Fecha y Hora: Una combinación de fecha y hora, por ejemplo, 2023-10-27 10:00:00.
{
"type": "dateTime",
"value": {},
"marker": "date_time",
"position": 7,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "DateTime"
},
"additionalFields": {}
}

  • Fecha: Una fecha, por ejemplo, 2023-10-27.
{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": {}
}

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

  • Archivo: Cualquier archivo, por ejemplo, un documento, imagen, 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": {}
}

  • Imagen: Una imagen, por ejemplo, una fotografía o un dibujo.
{
"type": "image",
"value": {},
"marker": "image",
"position": 11,
"listTitles": [],
"validators": {
"sizeInPixelsValidator": {
"maxX": "500",
"maxY": "500"
}
},
"localizeInfos": {
"title": "Image"
},
"additionalFields": {}
}

  • Grupo de Imágenes: Una colección de imágenes, por ejemplo, un álbum de fotos.
{
"type": "groupOfImages",
"value": {},
"marker": "image_group",
"position": 12,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Image Group"
},
"additionalFields": {}
}

  • Botón de Opción: Una selección de la cual solo se puede elegir una opción.
{
"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: Una lista de elementos seleccionables, por ejemplo, un desplegable.
{
"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": {}
}

  • Entidad: Un enlace a otro objeto (página, producto, …).
{
"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 tiempo: Un calendario flexible con una interfaz amigable para gestionar datos de intervalos de tiempo.
{
"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
}
}

La interfaz de llenado de contenido en el panel de administración corresponde al tipo de dato seleccionado para cada campo de atributo.


❓ Preguntas Comunes (FAQ)

¿Cuál es la diferencia entre string y text?

  • string - texto corto, una línea (máx. ~255 caracteres). Úsalo para nombres, títulos, correos electrónicos.
  • text - texto largo, múltiples párrafos, admite formato y HTML. Úsalo para descripciones, artículos.

¿Cuándo debo usar integer, float o real?

  • integer - solo números enteros (1, 2, 100, -5). Úsalo para cantidades, conteos, edades.
  • float - números decimales (19.99, 4.5). Úsalo para precios, calificaciones, medidas.
  • real - como float pero con mayor precisión. Úsalo para cálculos científicos.

¿Puedo reutilizar el mismo atributo en diferentes conjuntos de atributos?

Los atributos se definen dentro del esquema de un conjunto de atributos (por marcador). Para reutilizar un campo en otro lugar, crea atributos similares con diferentes marcadores o reutiliza todo el conjunto de atributos en múltiples entidades.


¿Qué es el "marcador" y por qué es importante?

El marcador es el identificador técnico que usas en el código (por ejemplo, product.attributeValues.product_name), a diferencia del título legible por humanos que se muestra en el panel de administración. Los marcadores deben ser únicos, no contener espacios (usar _), no comenzar con un número y convencionalmente estar en minúsculas.


¿Puedo tener atributos anidados?

Sí - usa Campos Adicionales (devueltos bajo additionalFields).


¿Cómo agrego reglas de validación?

En el panel de administración de OneEntry: abre tu conjunto de atributos, haz clic en un atributo, agrega validadores (requerido, min/max, etc.) y guarda. Aprende más: Validadores.


🎓 Mejores Prácticas

  • Usa marcadores descriptivos (product_price, no pp).
  • Planifica los tipos de atributos antes de agregar contenido.
  • Reutiliza conjuntos de atributos en entidades cuando sea posible.
  • Agrega validadores para hacer cumplir la calidad de los datos.
  • Recuerda que los conjuntos compartidos propagan cambios a cada entidad que los utiliza.

🔗 Documentación Relacionada