Content

Dernière mise à jour : 3 juillet 2026

Un Content est une donnée concrète instanciée à partir d'un Content Type (le moule). Prenons l'exemple d'une boutique de vêtements en ligne : le Content Type « Produit » définit la composition des champs comme le nom du produit, le prix ou la description détaillée, et un exemplaire « 스테인리스 텀블러 500ml » est un Content qui suit ce moule.

Un Content se compose de deux parties. fields contient la valeur réelle de chaque champ, et sys porte des états comme la publication, la version ou l'archivage. Sur la CMA, un Content est une sous-ressource d'un Space ; les chemins de consultation et de suppression s'appuient sur /spaces/{spaceId}/contents, tandis que les chemins de création et de modification s'appuient sur /spaces/{spaceId}/content-types/{contentTypeId}/contents, sous le Content Type. Les opérations de gestion s'effectuent sur la CMA, et l'instantané publié est délivré par la CDA.

Structure de la ressource

Voici la réponse de la consultation unitaire du Content publié « 스테인리스 텀블러 500ml ». Outre sys (propriétés système), il possède fields (valeurs des champs) et metadata (informations complémentaires telles que les tags).

{
  "sys": {
    "id": "3trmXRM3RqbgSnifyg7PUl8DzDgDzP",
    "type": "Content",
    "space": { "sys": { "id": "HnQ32YiH", "type": "Refer", "targetType": "Space" } },
    "contentType": { "sys": { "id": "3trmXRLdJF4GBlAjtcuoZ7Pnxj8dlA", "type": "Refer", "targetType": "ContentType" } },
    "publish": {
      "version": 1,
      "at": "2026-06-18T09:51:44.128Z",
      "firstAt": "2026-06-18T09:51:44.128Z",
      "counter": 1,
      "by": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } }
    },
    "createdBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "createdAt": "2026-06-18T09:51:14.597Z",
    "updatedBy": { "sys": { "id": "3p4tcFbQRwz503VXdtHXNI5dZH5TVB", "type": "Refer", "targetType": "User" } },
    "updatedAt": "2026-06-18T09:51:44.128Z",
    "version": 2,
    "status": "Published"
  },
  "fields": {
    "price": { "en-US": 18000 },
    "productName": { "en-US": "Stainless Tumbler 500ml", "ko-KR": "스테인리스 텀블러 500ml" }
  },
  "metadata": { "tags": [] }
}

Clés principales :

  • sys.id : identifiant unique du Content. Il s'insère dans le {contentId} des chemins de consultation unitaire, de modification, de suppression et de publication.
  • sys.contentType : le Refer qui pointe vers le Content Type que suit ce Content.
  • fields : les valeurs de chaque champ. La clé est l'apiName du champ, et la valeur est une carte par Locale. Voir La clé de fields est l'apiName ci-dessous.
  • metadata.tags : la liste des Tag attachés à ce Content. Chaque élément a la forme Refer<Tag> ; en l'absence de tag, c'est un tableau vide [].

La clé de fields est l'apiName

La clé de l'objet fields est l'apiName de chaque champ. Ce n'est ni l'id interne du Content Type, ni le nom du champ visible dans le studio de contenu (par exemple Nom du produit). Pour créer ou lire un Content, il faut donc utiliser comme clé l'apiName défini dans le Content Type.

Voici les champs du Content Type de démonstration « Produit » et leur correspondance avec l'apiName.

Nom dans le studio de contenuapiNametypelocalizedrequired
Nom du produitproductNameShortTexttruetrue
PrixpriceLongfalsefalse
DescriptiondescriptionRichTexttruefalse
PhotophotoRefer<Media>falsefalse
MarquebrandReferfalsefalse

La valeur de chaque champ est une carte par Locale. La forme de la valeur dépend de localized.

  • Un champ localized: true peut porter plusieurs valeurs de Locale sous la forme { "<locale>": valeur }. Exemple : "productName": { "en-US": "Stainless Tumbler 500ml", "ko-KR": "스테인리스 텀블러 500ml" }.
  • Un champ localized: false (champ non localisé) ne reçoit une valeur que sous une seule clé, celle du Locale par défaut du Space. Aucune autre clé de Locale n'est admise. Le Locale par défaut du Space de démonstration étant en-US, le prix ne porte qu'une seule clé en-US, comme dans "price": { "en-US": 18000 }.

Le Locale par défaut, la question de savoir jusqu'à quel Locale il faut remplir un champ required, ainsi que les règles de fallback en l'absence de valeur, sont traités dans Multilingue (concept).

Forme de la valeur selon le type

La forme de la valeur placée à l'intérieur d'une clé de Locale dépend du type du champ. La plupart des types reçoivent directement la valeur propre à ce type (les types texte reçoivent une chaîne, Number et Long un nombre, Boolean true/false). Voici les types dont la forme, objet ou tableau, prête facilement à confusion.

  • Location : c'est un objet { "latitude": <nombre>, "longitude": <nombre> }. latitude est compris entre -90 et 90, longitude entre -180 et 180, et les deux clés sont obligatoires. Aucune clé autre que celles définies n'est acceptée, si bien que des clés abrégées comme lat, lng ou lon sont rejetées.
  • Refer : la valeur est un objet Refer qui pointe vers la cible ; on n'y place pas une simple chaîne d'id mais l'objet sys tel quel. S'il pointe vers un autre Content, son targetType vaut Content ; s'il pointe vers un Media, il vaut Media. La forme du Refer elle-même est définie dans La forme Refer des propriétés système (sys).
  • Array : c'est un tableau JSON contenant les valeurs du type des éléments. Si les éléments sont du texte, c'est un tableau de chaînes ; si les éléments sont des Refer (Content ou Media), c'est un tableau d'objets Refer. Ce n'est pas un tableau de chaînes d'id.

Voici un exemple des valeurs placées à l'intérieur de fields (lorsque le Locale par défaut du Space est en-US).

{
  "location": { "en-US": { "latitude": 37.5662, "longitude": 126.9910 } },
  "tags": { "en-US": ["nouveauté", "édition limitée"] },
  "photo": { "en-US": { "sys": { "type": "Refer", "id": "3trmXRM3RqbgSnifyg7PUl8DzDgDzP", "targetType": "Media" } } },
  "photos": { "en-US": [ { "sys": { "type": "Refer", "id": "3trmXRM3RqbgSnifyg7PUl8DzDgDzP", "targetType": "Media" } } ] }
}

Propriétés système (sys)

Tout Content porte ses propriétés système communes dans l'objet sys. space, contentType, createdBy et updatedBy se présentent sous la forme Refer ({ "sys": { "id", "type": "Refer", "targetType" } }).

PropriétéTypeDescription
idstringIdentifiant unique de la ressource.
typestringNature de la ressource. Pour un Content, toujours "Content".
spaceRefer<Space>Le Space auquel appartient ce Content.
contentTypeRefer<ContentType>Le Content Type que suit ce Content.
publishobjectPointeur d'état de publication. Voir les clés ci-dessous.
archiveobjectInformations d'archivage. Présent uniquement lorsque la ressource est archivée, sinon la clé est absente. Voir les clés ci-dessous.
createdByRefer<User>L'utilisateur qui a créé la ressource.
createdAtstring (date-time)Date de création.
updatedByRefer<User>Le dernier utilisateur ayant modifié la ressource.
updatedAtstring (date-time)Date de la dernière modification.
versioninteger (≥1)Version de la ressource. Augmente de 1 à chaque changement : création, modification, publication, dépublication, archivage, etc.
statusstring (enum)État de publication. L'une des 4 valeurs ci-dessous.

status est l'une des 4 valeurs suivantes.

statusSignification
DraftEn cours de rédaction et pas encore publié.
ChangedDéjà publié une fois, puis modifié, avec des changements non encore publiés.
PublishedPublié et sans changement non publié.
ArchivedÉtat archivé.

L'objet publish est un pointeur qui indique l'état de publication. Lorsque la ressource est publiée, il porte toutes les clés suivantes.

CléTypeDescription
versionintegerLe sys.version au moment de la publication.
atstring (date-time)Date de la dernière publication.
firstAtstring (date-time)Date de la première publication. Conservée même après une dépublication.
counterintegerNombre cumulé de publications.
byRefer<User>Le dernier utilisateur ayant publié.

Lors d'une dépublication, version, at et by disparaissent de publish, et seuls firstAt et counter subsistent. Si la ressource n'a jamais été publiée, publish vaut { "counter": 0 }.

L'objet archive n'existe que lorsque la ressource est archivée. Dans ce cas, il porte version (le sys.version au moment de l'archivage), at (date d'archivage) et by (l'utilisateur qui a archivé) ; si la ressource n'est pas archivée, la clé archive elle-même est absente.

Dans les exemples ci-dessous, le sys.version et toutes les valeurs de date correspondent au moment réel de l'appel et varient d'un appel à l'autre.

Publication, version et concurrence

Le cycle de vie d'un Content est le suivant.

  • À la création, status vaut Draft. Un Content n'est pas publié automatiquement à la création. C'est une différence avec le Content Type. Le Content Type est publié automatiquement dès sa création, alors qu'un Content exige un appel de publication distinct pour rejoindre le chemin de délivrance.
  • Après publication, status passe à Published.
  • Si la ressource est modifiée après publication, status passe à Changed. Cela signifie qu'il existe des changements non publiés.
  • Après dépublication, status revient à Draft.
  • Pour archiver, il faut d'abord dépublier. Un Content à l'état publié ne peut pas être archivé directement.

sys.version augmente de 1 à chaque changement.

Les requêtes de modification, de modification partielle, de publication, de dépublication, d'archivage et de désarchivage doivent porter le sys.version courant dans l'en-tête x-weegloo-version. Si cette valeur est absente ou diverge de la version courante, la requête est considérée comme un conflit de modification concurrente et est rejetée. Les requêtes de création et de suppression ne portent pas cet en-tête. Les transitions d'état comme la publication, la dépublication, l'archivage et le désarchivage n'ont pas de corps de requête.

API

Pour tous les endpoints ci-dessous, l'URL de base est https://cma.weegloo.com/v1, et un jeton Bearer authentifiant la CMA est requis dans l'en-tête Authorization. La modification, la modification partielle, la publication, la dépublication, l'archivage et le désarchivage doivent aussi envoyer l'en-tête X-Weegloo-Version (le sys.version courant de la ressource) pour le contrôle de concurrence optimiste.

Lorsque vous filtrez ou triez la liste /contents (GET /spaces/{spaceId}/contents) par fields.*, vous devez aussi indiquer le Content Type avec sys.contentType.sys.id={contentTypeId}. La forme contentType={contentTypeId} ne peut pas s'y substituer. Le chemin /content-types/{contentTypeId}/contents porte le Content Type dans son chemin, il n'est donc pas nécessaire de l'indiquer séparément.

  • Content Type : le moule de ce Content (définition des champs, apiName).
  • CDA Content : délivrer (en lecture) aux visiteurs le Content publié.
  • Tag : étiquette de classification attachée via metadata.tags.
  • Multilingue (concept) : Locale par défaut, remplissage obligatoire, fallback.