Skip to main content

Introduction

Define custom fields for your content without touching code.

🎯 What does this module do?​

The AttributesSets module lets you use custom fields for your content (products, pages, forms, etc.) without hardcoding them in your application.

Think of it as a form builder for your data - you define what fields you need, and OneEntry handles the rest.

πŸ“– Simple Explanation​

Imagine you're building an online store. Each product needs:

  • Name (text).
  • Price (number).
  • Image (picture).
  • Description (long text).
  • Category (dropdown).

Instead of hardcoding these fields in your app, you use Attributes to define them in OneEntry admin panel. Then you can:

  • Add new fields anytime (no code changes!).
  • Reuse fields across different content types.
  • Change field types without redeploying.
  • Manage all content structure in one place.

Real-world example:

Without Attributes (hardcoded):
- Code: const product = { name: 'Product name', price: 150, image: '', description: '' }
- To add "color" field β†’ Change code, redeploy, wait.

With Attributes (dynamic):
- Code: const { name, price, image, description } = product
- Admin panel: Add "color" attribute.
- Code automatically includes new field.
- Code: const { name, price, image, description, color } = product
- No deployment needed!

✨ Key Concepts​

What is an Attribute?​

An attribute is a single field that stores data.

Examples:

  • Product name (string).
  • Product price (float).
  • Product image (image).
  • Publish date (date).

What is an Attribute Set?​

An attribute set is a collection of attributes that define a structure.

Example: Product Attribute Set

- name (string)
- price (float)
- description (text)
- images (group of images)
- category (list)
- inStock (integer)

Why Use Attribute Sets?​

❌ Without Attributesβœ… With Attributes
Hardcoded fieldsDynamic fields
Code changes neededEdit in admin panel
Redeploy requiredLive updates
Rigid structureFlexible structure
Duplicate codeReusable sets

πŸ“‹ What You Need to Know​

Three Important Terms​

TermWhat It IsExample
MarkerUnique code identifier"product_name"
TypeWhat kind of data it stores"string", "integer", "image"
ValueAttribute value"Product Name"

Important about Markers:

  • Must be unique
  • No spaces allowed (use _ instead)
  • Can't start with a number
  • Use lowercase for consistency

Examples:

  • βœ… Good: product_name, price_usd, main_image
  • ❌ Bad: product name, 2nd_price, Product Name

πŸ“š Available Data Types​

Attributes can store different types of data. Choose the right type for each field.

Quick Reference Table​

TypeBest ForExample Use
stringShort textProduct name, email
textLong formatted textBlog post, description
textWithHeaderText with titleArticle sections
integerWhole numbersQuantity, age
realHigh-precision decimalsScientific data
floatDecimal numbersPrice, rating
dateJust the dateBirth date, deadline
dateTimeDate + timeEvent start, published at
timeJust the timeOpening hours
fileAny filePDF, document
imageSingle imageAvatar, logo
groupOfImagesMultiple imagesPhoto gallery
radioButtonSingle choiceSize (S/M/L)
listDropdown selectionCountry, category
entityLink to other contentRelated products
timeIntervalDate rangePromotion period
jsonCustom structured dataAPI response

πŸ” Detailed Data Type Descriptions​

Text Types​

When to use what:

  • string - Single line, under 255 characters (name, email, title)
  • text - Multiple paragraphs, supports formatting (articles, descriptions)
  • textWithHeader - Text that needs a headline (blog sections, FAQs)

Number Types​

When to use what:

  • integer - No decimals needed (age, quantity, views)
  • float - Standard decimals (price $19.99, rating 4.5)
  • real - Extra precision needed (scientific calculations)

Date/Time Types​

When to use what:

  • date - Just the day (birthday, deadline)
  • time - Just the hour (business hours, appointment time)
  • dateTime - Both needed (event start, article published)
  • timeInterval - Period between dates (sale duration, vacation dates)

File & Image Types​

When to use what:

  • file - Any document (PDF, DOC, ZIP)
  • image - One picture (product photo, avatar)
  • groupOfImages - Multiple pictures (gallery, product images)

Selection Types​

When to use what:

  • radioButton - Pick only ONE option (Yes/No, Size S/M/L)
  • list - Dropdown with options (Country, Category, Status)

Advanced Types​

  • entity - Link to other pages/products (Related Items, Categories)
  • json - Store complex data structures (API responses, settings)

πŸ“– Data Type Examples​

Below are technical examples of each data type's structure.

πŸ’‘Data returned in the attribute set does not include actual attribute values, as these values are contained within specific entities such as pages, products, etc. The only exception is timeInterval attribute type. This attribute can have values ​​by checking the corresponding box in the admin panel

Click to see all data type examples

Data Types Reference​

Data types can be of the following types:

  • String: Simple text, for example, "Hello, world!".

Example:

{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "Extra"
}
]
}

  • Text: Longer text, often formatted, for example, an article or a letter.

Example:

{
"type": "text",
"value": {},
"marker": "text",
"position": 2,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text"
},
"additionalFields": []
}

  • Text with Header: Text with a header that can be used to denote a topic or category.

Example:

{
"type": "textWithHeader",
"value": {},
"marker": "text_with_header",
"position": 3,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text With Header"
},
"additionalFields": []
}

  • Integer: An integer, for example, 5, 100, -2.

Example:

{
"type": "integer",
"value": {},
"marker": "integer",
"position": 4,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Integer"
},
"additionalFields": []
}

  • Real: The same as Float, but with higher precision.

Example:

{
"type": "real",
"value": {},
"marker": "real_number",
"position": 5,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Real Number"
},
"additionalFields": []
}

  • Float: A data type for floating-point numbers that can have a decimal part, for example, 3.14, 1.5, -0.25.

Example:

{
"type": "float",
"value": {},
"marker": "float",
"position": 6,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Float"
},
"additionalFields": []
}

  • Date and Time: A combination of date and time, for example, 2023-10-27 10:00:00.

Example:

{
"type": "dateTime",
"value": {},
"marker": "date_time",
"position": 7,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "DateTime"
},
"additionalFields": []
}

  • Date: A date, for example, 2023-10-27.

Example:

{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": []
}

  • Time: A time, for example, 10:00:00.

Example:

{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": []
}

  • File: Any file on your computer, for example, a document, image, music.

Example:

{
"type": "file",
"value": {},
"marker": "file",
"position": 10,
"listTitles": [],
"validators": {
"checkingFilesValidator": {
"maxUnits": "kb",
"maxValue": "2000",
"minUnits": "kb",
"minValue": 0,
"extensions": []
}
},
"localizeInfos": {
"title": "File"
},
"additionalFields": []
}

  • Image: An image, for example, a photograph, drawing.

Example:

{
"type": "image",
"value": {},
"marker": "image",
"position": 11,
"listTitles": [],
"validators": {
"sizeInPixelsValidator": {
"maxX": "500",
"maxY": "500"
}
},
"localizeInfos": {
"title": "Image"
},
"additionalFields": []
}

  • Group of Images: A collection of images, for example, a photo album.

Example:

{
"type": "groupOfImages",
"value": {},
"marker": "image_group",
"position": 12,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Image Group"
},
"additionalFields": []
}

  • Radio Button: A selection button from which only one option can be chosen.

Example:

{
"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: A list of items, for example, a shopping list.

Example:

{
"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": []
}

  • Entity: An entity representing an object.

Example:

{
"type": "entity",
"value": {},
"marker": "entity",
"position": 15,
"listTitles": [
{
"title": "Products",
"value": {
"id": 1,
"depth": 0,
"parentId": null,
"position": 1,
"selected": true
}
},
{
"title": "Normal Page",
"value": {
"id": 4,
"depth": 0,
"parentId": null,
"position": 2,
"selected": true
}
},
{
"title": "Error",
"value": {
"id": 2,
"depth": 0,
"parentId": null,
"position": 3,
"selected": true
}
}
],
"validators": {},
"localizeInfos": {
"title": "Entity"
},
"additionalFields": [
{
"type": "string",
"value": "Test Field",
"marker": "test_field"
}
]
}

  • Time interval: A flexible calendar with a user-friendly interface for managing time interval data.

Example:

{
"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": {
"en_US": {
"title": "Time interval"
}
},
"receiveValues": true
}
}

  • JSON: Some data in JSON format.

Example:

{
"type": "json",
"value": {},
"marker": "json",
"position": 17,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Json"
},
"additionalFields": []
}

The content filling interface will correspond to the selected data type for each attribute field.


πŸ’‘ Important Notes​

Validators​

You can add validators for attributes to ensure data quality:

  • Required fields.
  • Min/max length for text.
  • File size limits for uploads.
  • Pixel dimensions for images.
  • Date ranges.
Click to see validators examples
  • requiredValidator: Requires a value to be entered.

Example:

{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "Currency"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "extra"
}
]
}

  • defaultValueValidator:

Example:

{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"defaultValueValidator": {
"customErrorText": "Custom error",
"fieldDefaultValue": "usd",
"fieldDefaultValue2": "",
},
},
"localizeInfos": {
"title": "String"
},
"additionalFields": [
{
"type": "integer",
"value": "10",
"marker": "extra"
}
]
}

Learn more: See Validators section for detailed configuration.

Shared Attribute Sets​

⚠️ Important: If an attribute set is used by multiple entities, be careful when making changes:

Adding an attribute:

  • It will be added to all entities that use the set.
  • Existing content remains unchanged.
  • The new field will be empty for existing items.

Removing an attribute:

  • It will be removed from all entities that use the set.
  • Existing values will be permanently deleted.

Example:

"Product Info" attribute set used by:
- Physical Products
- Digital Products
- Services

Adding "weight" attribute β†’ Added to ALL three!
Removing "weight" attribute β†’ Removed from ALL three! ⚠️

πŸ“Š Quick Reference Table - Common Methods​

MethodWhat It Does
getAttributes()Getting all attributes sets objects.
getAttributesByMarker()Getting all attributes by marker with data from the attribute set.
getAttributeSetByMarker()Getting a single object of attributes set by marker.
getSingleAttributeByMarkerSet()Getting one attribute with data from the attribute set.

❓ Common Questions (FAQ)​

What's the difference between string and text?​

  • string - Short text, single line (max ~255 chars). Use for names, titles, emails.
  • text - Long text, multiple paragraphs, supports formatting and HTML. Use for descriptions, articles.

When should I use integer vs float?​

  • integer - Whole numbers only: 1, 2, 100, -5. Use for quantities, counts, ages.
  • float - Decimal numbers: 19.99, 4.5, -0.25. Use for prices, ratings, measurements.
  • real - Like float but higher precision. Use for scientific calculations.

Best practice: Plan your attribute types before adding content.


What happens if I delete an attribute?​

  • You cant delete an attribute if it is used in an attribute set.

Can I reuse the same attribute in different attribute sets?​

No, each attribute belongs to one attribute set. But you can:

  • Create similar attributes with different markers
  • Reuse entire attribute sets across multiple entities

What's the "marker" and why is it important?​

The marker is the technical identifier you use in code:

// In your code:
product.attributeValues.product_name // ← "product_name" is the marker

// VS the name (shown in admin):
"Product Name" // ← This is just for humans

Rules for markers:

  • Must be unique
  • No spaces (use _)
  • Can't start with numbers
  • Use lowercase
  • Choose descriptive names

How do I know which type to use for my data?​

Ask yourself:

  1. Is it text?

    • Short (< 255 chars)? β†’ string
    • Long with formatting? β†’ text
    • Needs a title? β†’ textWithHeader
  2. Is it a number?

    • No decimals? β†’ integer
    • Has decimals? β†’ float
    • Scientific precision? β†’ real
  3. Is it a choice?

    • Pick one option? β†’ radioButton
    • Dropdown menu? β†’ list
  4. Is it a file?

    • Picture? β†’ image or groupOfImages
    • Document? β†’ file
  5. Is it a date?

    • Just date? β†’ date
    • Date + time? β†’ dateTime
    • Time period? β†’ timeInterval

Can I have nested attributes (attributes inside attributes)?​

Yes, you can use Additional Fields


How do I add validation rules?​

In OneEntry admin panel:

  1. Go to your attribute set
  2. Click on an attribute
  3. Add validators (required, min/max, regex, etc.)
  4. Save changes

Learn more: See Validators section for detailed configuration.


πŸŽ“ Best Practices​

  • Use descriptive markers (product_price not pp)
  • Plan attribute types before adding content
  • Reuse attribute sets when possible
  • Add validators to ensure data quality
  • Document what each attribute is for

More information about the module's user interface https://doc.oneentry.cloud/docs/attributes/introduction

Definition of the AttributesSets module​


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