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, price, image, description }
- To add "color" field → Change code, redeploy, wait.

With Attributes (dynamic):
- Admin panel: Add "color" attribute.
- Code automatically includes new field.
- 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

Reusability

Attribute sets can be reused across different entities:

"Basic Info" Attribute Set:
- title (string)
- description (text)
- publish_date (date)

Used by:
- Blog posts
- News articles
- Product pages
- Event listings

Why this matters: Change once, updates everywhere!


📚 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.

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.

Learn more: See "Validators" section for detailed configuration.

Shared Attribute Sets

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

Deleting an attribute:

  • Removes it everywhere the set is used.
  • Deletes all content in that field.
  • Cannot be undone!

Adding an attribute:

  • Added everywhere the set is used.
  • Existing content unchanged.
  • New field will be empty for existing items.

Example:

"Product Info" used by:
- Physical Products.
- Digital Products.
- Services.

Delete "weight" attribute → Removed from ALL three! ⚠️

📊 Quick Reference Table - Common Methods

MethodWhat It DoesWhen to Use
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)?

Not directly, but you can use:

  • entity type to link to other content
  • json type to store structured data
  • Multiple attribute sets to organize related 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

Common validators:

  • Required field
  • Min/max length
  • Email format
  • URL format
  • File size limits
  • Image dimensions

🎓 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"
}
);