Aller au contenu principal

Introduction

Définissez des champs personnalisés pour votre contenu sans toucher au code.

Plus d'informations sur l'interface utilisateur du module https://doc.oneentry.cloud/docs/category/attributes


🎯 Que fait ce module ?

Le module AttributesSets vous permet de lire les définitions de champs personnalisés (ensembles d'attributs) utilisés par votre contenu - produits, pages, formulaires, blocs, et plus encore. Un ensemble d'attributs est le schéma qui décrit quels champs une entité possède et quel type chaque champ est ; vous les définissez dans le panneau d'administration OneEntry et récupérez leur structure avec ce module.

Remarque : les ensembles d'attributs décrivent le schéma, pas les valeurs. Les valeurs réelles se trouvent sur les entités elles-mêmes (une page, un produit, etc.) sous leurs attributeValues. La seule exception est le type timeInterval, qui peut contenir des valeurs - voir les exemples ci-dessous.

🚀 Démarrage rapide

Initialisez le module depuis defineOneEntry :


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

Récupérez les attributs définis dans un ensemble et lisez leurs marqueurs et types :

// 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);
});

✨ Concepts clés

Attribut, Ensemble d'attributs, Valeur

TermeCe que c'estExemple
AttributUne définition de champ unique (un marqueur + un type)price (float)
Ensemble d'attributsUne collection d'attributs - le schéma de l'entitéEnsemble "Produit"
ValeurLes données qu'une entité stocke pour un attribut19.99 sur un produit spécifique

Un ensemble d'attributs regroupe des attributs dans un schéma réutilisable. Le même ensemble peut être attaché à plusieurs entités, donc changer l'ensemble change les champs disponibles partout où il est utilisé.

Marqueurs

Le marqueur est l'identifiant technique que vous utilisez dans le code (par exemple, product_name). Il correspond au titre lisible par l'homme affiché dans le panneau d'administration.

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

Règles de marqueur :

  • Doit être unique
  • Pas d'espaces (utilisez _)
  • Ne peut pas commencer par un chiffre
  • Utilisez des minuscules pour la cohérence

✅ Bon : product_name, price_usd, main_image — ❌ Mauvais : product name, 2nd_price, Product Name

📋 Ce que vous devez savoir

Ensembles d'attributs partagés

Si un ensemble d'attributs est utilisé par plusieurs entités, les modifications se propagent à toutes :

  • Ajout d'un attribut - il apparaît sur chaque entité utilisant l'ensemble ; le contenu existant conserve ses valeurs et le nouveau champ commence vide.
  • Suppression d'un attribut - il est supprimé de chaque entité utilisant l'ensemble, et les valeurs existantes sont définitivement supprimées.

Vous ne pouvez pas supprimer un attribut tant qu'il est encore utilisé dans un ensemble d'attributs.

Validateurs

Les attributs peuvent comporter des validateurs pour garantir la qualité des données - champs requis, longueur min/max, limites de taille de fichier, dimensions en pixels d'image, plages de dates, et une valeur par défaut. La configuration du validateur est renvoyée sur chaque attribut sous validators.

Cliquez pour voir des exemples de validateurs
  • requiredValidator : nécessite qu'une valeur soit saisie.
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "Currency"
},
"additionalFields": {
"extra": {
"type": "integer",
"value": "10",
"marker": "extra"
}
}
}

  • defaultValueValidator : fournit une valeur par défaut pour le champ.
{
"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"
}
}
}

En savoir plus : Consultez Validators pour une configuration détaillée.

Attributs imbriqués

Vous pouvez attacher des champs supplémentaires à un attribut via Champs supplémentaires (renvoyé sous additionalFields).


📊 Tableau de référence rapide - Méthodes courantes

MéthodeCe qu'elle fait
getAttributes()Récupère tous les objets d'ensemble d'attributs.
getAttributesByMarker()Récupère tous les attributs d'un ensemble, avec des données de l'ensemble d'attributs.
getAttributeSetByMarker()Récupère un seul objet d'ensemble d'attributs par marqueur.
getSingleAttributeByMarkerSet()Récupère un attribut (avec des données d'ensemble) par marqueur d'ensemble et marqueur d'attribut.

📚 Types de données disponibles

Chaque attribut a un type. Choisissez le bon type pour chaque champ.

TypeMeilleur pourUtilisation d'exemple
stringTexte court (< 255 caractères)Nom du produit, email
textTexte long formatéArticle de blog, description
textWithHeaderTexte avec un titreSections d'article
integerNombres entiersQuantité, âge
realDécimales de haute précisionDonnées scientifiques
floatNombres décimauxPrix, évaluation
dateJuste la dateDate de naissance, date limite
dateTimeDate + heureDébut d'événement, publié à
timeJuste l'heureHeures d'ouverture
fileTout fichierPDF, document
imageImage uniqueAvatar, logo
groupOfImagesPlusieurs imagesGalerie photo
radioButtonChoix uniqueTaille (S/M/L)
listSélection déroulantePays, catégorie
buttonAction interactiveSoumettre le formulaire, CTA
spamProtection contre le spamChamp anti-bot honeypot
entityLien vers un autre contenuProduits connexes
timeIntervalPlages de date/heureHoraires, période de promotion

Choisir un type

  • Texte : string (ligne unique), text (paragraphes formatés), textWithHeader (texte avec un titre).
  • Nombres : integer (pas de décimales), float (décimales standard), real (précision supplémentaire).
  • Date/heure : date, time, dateTime, ou timeInterval (plages/horaire).
  • Fichiers/images : file (tout document), image (une image), groupOfImages (une galerie).
  • Choix : radioButton (choisir un), list (déroulant).
  • Avancé : entity (lien vers d'autres pages/produits), button (action interactive), spam (protection contre les bots).

📖 Exemples de types de données

Voici des exemples techniques de la structure de chaque type de données tel que renvoyé par l'API.

💡 Les données renvoyées dans l'ensemble d'attributs ne comprennent pas les valeurs d'attribut réelles - celles-ci se trouvent sur des entités spécifiques (pages, produits, etc.). La seule exception est timeInterval, qui peut contenir des valeurs lorsque la case correspondante est cochée dans le panneau d'administration.

Cliquez pour voir tous les exemples de types de données

Référence des types de données

  • String : Texte simple, par exemple, "Bonjour, le monde !".
{
"type": "string",
"value": {},
"marker": "string",
"position": 1,
"listTitles": [],
"validators": {
"requiredValidator": {
"strict": true
}
},
"localizeInfos": {
"title": "String"
},
"additionalFields": {
"Extra": {
"type": "integer",
"value": "10",
"marker": "Extra"
}
}
}

  • Text : Texte plus long, souvent formaté, par exemple, un article ou une lettre.
{
"type": "text",
"value": {},
"marker": "text",
"position": 2,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text"
},
"additionalFields": {}
}

  • Text with Header : Texte avec un en-tête qui peut être utilisé pour désigner un sujet ou une catégorie.
{
"type": "textWithHeader",
"value": {},
"marker": "text_with_header",
"position": 3,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Text With Header"
},
"additionalFields": {}
}

  • Integer : Un entier, par exemple, 5, 100, -2.
{
"type": "integer",
"value": {},
"marker": "integer",
"position": 4,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Integer"
},
"additionalFields": {}
}

  • Real : La même chose que Float, mais avec une précision plus élevée.
{
"type": "real",
"value": {},
"marker": "real_number",
"position": 5,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Real Number"
},
"additionalFields": {}
}

  • Float : Un nombre à virgule flottante qui peut avoir une partie décimale, par exemple, 3.14, 1.5, -0.25.
{
"type": "float",
"value": {},
"marker": "float",
"position": 6,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Float"
},
"additionalFields": {}
}

  • Date et Heure : Une combinaison de date et d'heure, par exemple, 2023-10-27 10:00:00.
{
"type": "dateTime",
"value": {},
"marker": "date_time",
"position": 7,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "DateTime"
},
"additionalFields": {}
}

  • Date : Une date, par exemple, 2023-10-27.
{
"type": "date",
"value": {},
"marker": "date",
"position": 8,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Date"
},
"additionalFields": {}
}

  • Time : Une heure, par exemple, 10:00:00.
{
"type": "time",
"value": {},
"marker": "time",
"position": 9,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Time"
},
"additionalFields": {}
}

  • File : Tout fichier, par exemple, un document, une image, de la musique.
{
"type": "file",
"value": {},
"marker": "file",
"position": 10,
"listTitles": [],
"validators": {
"checkingFilesValidator": {
"maxUnits": "kb",
"maxValue": "2000",
"minUnits": "kb",
"minValue": 0,
"extensions": []
}
},
"localizeInfos": {
"title": "File"
},
"additionalFields": {}
}

  • Image : Une image, par exemple, une photographie ou un dessin.
{
"type": "image",
"value": {},
"marker": "image",
"position": 11,
"listTitles": [],
"validators": {
"sizeInPixelsValidator": {
"maxX": "500",
"maxY": "500"
}
},
"localizeInfos": {
"title": "Image"
},
"additionalFields": {}
}

  • Group of Images : Une collection d'images, par exemple, un album photo.
{
"type": "groupOfImages",
"value": {},
"marker": "image_group",
"position": 12,
"listTitles": [],
"validators": {},
"localizeInfos": {
"title": "Image Group"
},
"additionalFields": {}
}

  • Radio Button : Une sélection à partir de laquelle une seule option peut être choisie.
{
"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 : Une liste d'éléments sélectionnables, par exemple, un menu déroulant.
{
"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 : Un lien vers un autre objet (page, produit, …).
{
"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"
}
}
}

  • Time interval : Un calendrier flexible avec une interface conviviale pour gérer les données de plage horaire.
{
"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
}
}

L'interface de remplissage de contenu dans le panneau d'administration correspond au type de données sélectionné pour chaque champ d'attribut.


❓ Questions fréquentes (FAQ)

Quelle est la différence entre string et text ?

  • string - texte court, ligne unique (max ~255 caractères). Utilisez pour les noms, titres, emails.
  • text - texte long, plusieurs paragraphes, prend en charge le formatage et HTML. Utilisez pour les descriptions, articles.

Quand devrais-je utiliser integer, float ou real ?

  • integer - uniquement des nombres entiers (1, 2, 100, -5). Utilisez pour les quantités, les comptes, les âges.
  • float - nombres décimaux (19.99, 4.5). Utilisez pour les prix, les évaluations, les mesures.
  • real - comme float mais avec une précision plus élevée. Utilisez pour les calculs scientifiques.

Puis-je réutiliser le même attribut dans différents ensembles d'attributs ?

Les attributs sont définis dans le schéma d'un ensemble d'attributs (par marqueur). Pour réutiliser un champ ailleurs, soit créez des attributs similaires avec des marqueurs différents, soit réutilisez l'ensemble d'attributs entier à travers plusieurs entités.


Qu'est-ce que le "marqueur" et pourquoi est-il important ?

Le marqueur est l'identifiant technique que vous utilisez dans le code (par exemple, product.attributeValues.product_name), par opposition au titre lisible par l'homme affiché dans le panneau d'administration. Les marqueurs doivent être uniques, ne contenir aucun espace (utilisez _), ne pas commencer par un chiffre, et sont conventionnellement en minuscules.


Puis-je avoir des attributs imbriqués ?

Oui - utilisez Champs supplémentaires (renvoyé sous additionalFields).


Comment ajouter des règles de validation ?

Dans le panneau d'administration OneEntry : ouvrez votre ensemble d'attributs, cliquez sur un attribut, ajoutez des validateurs (requis, min/max, etc.), et enregistrez. En savoir plus : Validators.


🎓 Meilleures pratiques

  • Utilisez des marqueurs descriptifs (product_price, pas pp).
  • Planifiez les types d'attributs avant d'ajouter du contenu.
  • Réutilisez les ensembles d'attributs à travers les entités lorsque cela est possible.
  • Ajoutez des validateurs pour garantir la qualité des données.
  • N'oubliez pas que les ensembles partagés propagent les modifications à chaque entité qui les utilise.

🔗 Documentation connexe

  • Module Produits - Utilise des ensembles d'attributs pour les données produit
  • Module Pages - Utilise des ensembles d'attributs pour le contenu des pages
  • Module Blocs - Utilise des ensembles d'attributs pour des blocs réutilisables
  • Module Formulaires - Créez des formulaires avec des champs personnalisés