Spunto CMS
L'API

Brouillons et publication

Publier une carte, ne lire que ce qui a été publié, savoir ce qui a changé depuis — et les webhooks qu'un site écoute.

Toute carte est un brouillon jusqu'à ce qu'on la publie. Publier recopie ce que la carte dit — titre, icône, couverture, propriétés, corps — dans sa version publiée. Ce qu'on modifie ensuite reste dans le brouillon : un site qui lit la version publiée continue de servir l'ancien texte tant que la carte n'a pas été republiée.

Rien ne change pour un client qui ne demande rien. Sans version, toute lecture rend les brouillons, exactement comme avant.

Publier et dépublier

PUT    /workspaces/{workspaceId}/items/{itemId}/publication
DELETE /workspaces/{workspaceId}/items/{itemId}/publication

Les deux rendent la carte (ItemDetail) avec son état de publication à jour. Dans l'application, la tête de la carte montre son état et un bouton Publier ; Dépublier est dans le menu ⋯ de la carte.

  • Publier sans rien de neuf ne fait rien. Ni écriture, ni événement, ni webhook. Un double clic, un script relancé ou une app qui republie tout par précaution ne coûtent rien et ne réveillent personne.
  • Dépublier retire la version publiée. La carte redevient un brouillon, son contenu intact.
  • Une carte archivée ne se publie pas (409) : elle n'est dans aucune liste, un lecteur n'aurait rien à voir.
  • Publier est une écriture : il faut le rôle member, comme pour modifier. Pour une app installée, c'est un scope à part, items:publish — items:write ne suffit pas. Une app qui traduit ou corrige des brouillons ne doit pas pouvoir les mettre en ligne.

Ne lire que ce qui a été publié

Ajoutez "version": "published" à côté de la définition — pas dedans. Une vue enregistrée sert à la fois vos rédacteurs (le brouillon) et votre site (la version publiée) : la version dit qui lit, pas ce que la vue sélectionne.

POST /workspaces/{workspaceId}/collections/{collectionId}/query
{
  "definition": {
    "filter": { "op": "eq", "field": { "fieldId": "<slugFieldId>" }, "value": "bonjour" },
    "sort": [{ "field": { "fieldId": "sys:order" }, "direction": "asc" }],
    "includeSecondaryLists": false
  },
  "version": "published",
  "limit": 1
}

Le même champ vaut pour grouped-query et group-counts. Pour une seule carte :

GET /workspaces/{workspaceId}/items/{itemId}?version=published

Elle rend 404 si la carte n'est pas publiée ou est archivée — un site n'a pas à savoir lequel des deux.

Ce que rend une lecture publiée :

  • seulement les cartes publiées — une carte jamais publiée n'existe pas pour elle ;
  • ce que chaque carte disait à sa publication : titre, icône, couverture, propriétés et corps viennent de la version publiée. Filtres et tris portent sur ces valeurs : un slug modifié dans le brouillon ne correspond qu'une fois republié ;
  • là où la carte est rangée aujourd'hui : liste, listes secondaires, parent, ordre manuel et statut sont lus sur la carte telle qu'elle est. Déplacer une carte ou réordonner une liste ne demande pas de republier ;
  • updatedAt vaut l'instant de publication de la version.

Un curseur pris sur une lecture du brouillon est refusé sur une lecture publiée, et inversement : les deux ne listent pas les mêmes cartes.

Brouillon, publiée, modifiée

Chaque Item porte deux champs facultatifs :

publishedAtchangedSincePublicationÉtat
nullfalsebrouillon — jamais publiée, ou dépubliée
une datefalsepubliée, à jour
une datetruepubliée, et le brouillon a changé depuis

« Modifiée » veut dire que le contenu a changé : titre, icône, couverture, propriétés ou corps. Changer le statut, déplacer la carte ou la réordonner ne compte pas — rien de tout ça ne change ce que montre le site.

Pour filtrer ou grouper par état, utilisez le champ système sys:publication, dont les valeurs sont draft, published et changed. Une carte changed est toujours en ligne : « tout ce qui est publié » s'écrit { "op": "in", "field": { "fieldId": "sys:publication" }, "values": ["published", "changed"] }.

Deux champs, pas un énuméré

L'état est publié sous la forme d'une date et d'un booléen plutôt que d'un state à trois valeurs, exprès : un décodeur strict (le client iOS en est un) fait échouer la réponse entière sur une valeur d'énuméré qu'il ne connaît pas. Les deux champs sont facultatifs — absent veut dire « pas dit ici », pas « brouillon ».

Webhooks

Écoutez item.published et item.unpublished, pas item.updated : l'éditeur enregistre le brouillon toutes les secondes environ pendant qu'on écrit, et rien de tout ça ne change ce que sert votre site.

item.published porte publishedAt (avant / après) et, à une republication, ce que la nouvelle version change par rapport à la précédente — un slug avant et après, c'est l'ancienne adresse à invalider. Le corps lui-même ne voyage pas, seulement le fait qu'il a changé (bodyChanged). Une première publication ne porte que publishedAt.

Ce que ce n'est pas

Il n'y a ni publication programmée, ni historique des versions, ni route qui publie en masse, et une clé qui lit un espace en lit aussi les brouillons. Voir les limites.

Sur cette page