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 fields | Dynamic fields |
| Code changes needed | Edit in admin panel |
| Redeploy required | Live updates |
| Rigid structure | Flexible structure |
| Duplicate code | Reusable sets |
π What You Need to Knowβ
Three Important Termsβ
| Term | What It Is | Example |
|---|---|---|
| Marker | Unique code identifier | "product_name" |
| Type | What kind of data it stores | "string", "integer", "image" |
| Value | Attribute 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β
| Type | Best For | Example Use |
|---|---|---|
| string | Short text | Product name, email |
| text | Long formatted text | Blog post, description |
| textWithHeader | Text with title | Article sections |
| integer | Whole numbers | Quantity, age |
| real | High-precision decimals | Scientific data |
| float | Decimal numbers | Price, rating |
| date | Just the date | Birth date, deadline |
| dateTime | Date + time | Event start, published at |
| time | Just the time | Opening hours |
| file | Any file | PDF, document |
| image | Single image | Avatar, logo |
| groupOfImages | Multiple images | Photo gallery |
| radioButton | Single choice | Size (S/M/L) |
| list | Dropdown selection | Country, category |
| entity | Link to other content | Related products |
| timeInterval | Date range | Promotion period |
| json | Custom structured data | API 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β
| Method | What 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.