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 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
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
| 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.
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
| Method | What It Does | When 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:
-
Is it text?
- Short (< 255 chars)? →
string - Long with formatting? →
text - Needs a title? →
textWithHeader
- Short (< 255 chars)? →
-
Is it a number?
- No decimals? →
integer - Has decimals? →
float - Scientific precision? →
real
- No decimals? →
-
Is it a choice?
- Pick one option? →
radioButton - Dropdown menu? →
list
- Pick one option? →
-
Is it a file?
- Picture? →
imageorgroupOfImages - Document? →
file
- Picture? →
-
Is it a date?
- Just date? →
date - Date + time? →
dateTime - Time period? →
timeInterval
- Just date? →
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:
- Go to your attribute set
- Click on an attribute
- Add validators (required, min/max, regex, etc.)
- Save changes
Common validators:
- Required field
- Min/max length
- Email format
- URL format
- File size limits
- Image dimensions
🎓 Best Practices
- Use descriptive markers (
product_pricenotpp) - 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" });
🔗 Related Documentation
- Products Module - Uses attribute sets for product data
- Pages Module - Uses attribute sets for page content
- Blocks Module - Uses attribute sets for reusable blocks
- Forms Module - Create forms with custom fields