Internal Content API

Objectif

L'Internal Content API est une API CMS sécurisée destinée aux outils d'IA et d'opérateur de confiance. Elle leur permet d'inspecter les contrats de contenu du CMS, de créer du contenu en commençant par le brouillon, de remplacer des slots précis appartenant à la page sur des pages en brouillon existantes et d'exécuter des opérations de publication explicites via du JSON structuré, sans se connecter à l'interface d'administration du navigateur, sans l'extraire ni l'automatiser.

La phase 1 est implémentée sous la forme d'une API non publique, protégée par token et uniquement JSON, pour la découverte de contenu en lecture seule et la création de pages en brouillon via des plans de contenu validés. La phase 2A ajoute des fondations sûres pour les menus de navigation, les Shared Slots et l'affectation explicite de Shared Slots aux slots de page. La phase 2B ajoute le remplacement contrôlé, en brouillon uniquement, du contenu des slots appartenant à la page sur des pages existantes. Les endpoints de publication sont explicites et exigent content.publish ; content apply reste orienté brouillon et ne publie pas. L'API reste volontairement étroite : pas de récupération distante, pas de suppression large de pages via content apply, pas de remplacement des slots adossés à des Shared Slots et pas de publication en cascade des Shared Slots.

Positionnement produit

L'Internal Content API est :

  • une API CMS interne, destinée aux opérateurs
  • protégée par token
  • non publique
  • pas une API de diffusion de CMS headless
  • pas un substitut aux permissions d'administration
  • pas un substitut à l'import/export
  • pas une intégration avec un fournisseur d'IA

Le cœur du CMS doit être propriétaire de cette API, car elle porte sur des concepts de contenu du cœur : sites, pages, layouts, slots, blocs, traductions, navigation et shared slots. Les outils d'IA ou d'opérateur peuvent appeler l'API, mais le cœur du CMS ne doit pas embarquer de logique d'intégration OpenAI, LLM, crawler ou propre à un fournisseur.

Préfixe de route

Le préfixe canonique est :

/webadmin/api

L'API reste ainsi à l'intérieur de la frontière d'administration du CMS tout en utilisant un segment d'API concis et familier. Les endpoints de type ressource doivent se trouver directement sous ce préfixe, par exemple /webadmin/api/pages et /webadmin/api/blocks.

La découverte de l'API commence à :

GET /webadmin/api

Les appelants non authentifiés ne reçoivent que le JSON d'amorçage sûr pour le public. Les appelants authentifiés reçoivent des métadonnées sûres de version du produit ainsi que des liens vers OpenAPI, le guide IA, le contrat de contenu, les exemples, content validate/apply, les pages, la navigation et les Shared Slots. Les outils externes d'IA/opérateur doivent partir de cette réponse de découverte en direct plutôt que de lire le dépôt du CMS ou la documentation locale du paquet.

Les opérations de contenu fondées sur un plan utilisent :

POST /webadmin/api/content/validate
POST /webadmin/api/content/apply

Choix de routes à éviter :

  • /webadmin/internal-api, parce que c'est inutilement verbeux
  • /webadmin/api/content-plans/..., parce que content-plans est trop technique et trop étroit pour le contrat d'URL
  • placer toutes les ressources sous /webadmin/api/content/..., parce que les API de ressource doivent rester claires et directes
  • /admin, parce que le CMS ne doit pas supposer que le chemin /admin du produit hôte lui appartient
  • /cms, parce que /cms reste réservé aux seuls assets statiques du CMS

Authentification

L'API utilise l'authentification par token Bearer :

Authorization: Bearer <token>

Les tokens de l'API du CMS sont créés par un super administrateur du CMS depuis System -> API Tokens. Le CMS ne stocke qu'un hachage SHA-256 et un aperçu sûr dans la table de base de données cms_api_tokens. Le token en clair est affiché une seule fois, juste après sa création, et n'est plus jamais affiché.

Les super administrateurs peuvent révoquer un token pour désactiver immédiatement l'accès à l'API tout en gardant la ligne d'audit visible, ou supprimer un token pour retirer définitivement son enregistrement de la liste. Supprimer un token actif désactive aussi immédiatement l'accès à l'API, car l'authentificateur ne trouve plus de hachage stocké correspondant.

Les outils locaux d'IA et d'opérateur doivent conserver le token généré dans un coffre à secrets d'opérateur de confiance.

Utilisez l'URL de base de l'Internal Content API dans la configuration locale de l'opérateur :

WEBBLOCKS_CMS_API_URL=https://example.com/webadmin/api
WEBBLOCKS_CMS_API_TOKEN=...

L'exécution du CMS n'exige pas WEBBLOCKS_CMS_INTERNAL_API_TOKEN.

Règles d'authentification :

  • les tokens manquants, erronés ou révoqués renvoient un 401 JSON
  • les tokens révoqués cessent de fonctionner immédiatement
  • les tokens ne doivent jamais apparaître dans les journaux, les diagnostics, les rapports de support, les tests ou les exemples de documentation
  • la comparaison des tokens doit utiliser une comparaison à temps constant
  • les requêtes API réussies mettent à jour last_used_at et last_used_ip du token
  • les requêtes API réussies enregistrent également un user-agent tronqué comme contexte d'audit pour l'opérateur
  • les réponses sont uniquement en JSON

Exemple de requête :

GET /webadmin/api/sites
Authorization: Bearer <token>
Accept: application/json
Content-Type: application/json

Capacités

Les super administrateurs choisissent les capacités du token lors de sa création depuis System -> API Tokens, et peuvent ensuite modifier le nom et les capacités d'un token sans exposer ni faire tourner son secret. La découverte expose les capacités enregistrées sans renvoyer la valeur du token, son hachage ou son aperçu. Les tokens standard de construction de pages disposent par défaut de ces capacités :

  • content.read
  • content.validate
  • content.apply
  • navigation.write
  • shared-slots.write

Les capacités destructrices et de publication sont des options avancées distinctes et ne sont pas sélectionnées par défaut :

  • content.publish
  • pages.delete

Les endpoints d'écriture vérifient la capacité concernée côté serveur. Les capacités manquantes renvoient un 403 JSON accompagné des indications api_discovery_url, openapi_url, documentation_url et example_url. Les tokens ordinaires de construction de pages ne doivent pas inclure de capacités destructrices.

Modèle de l'API

L'API comporte deux modes complémentaires.

Resource API

Les endpoints de ressource reflètent les opérations équivalentes de l'administration, une par une :

  • lister et lire les pages
  • lister et lire les blocs
  • lister les sites, les langues (locales), les layouts et les types de bloc
  • plus tard, créer ou mettre à jour directement des ressources de page en brouillon
  • plus tard, lister ou garantir les slots de page
  • plus tard, ajouter, mettre à jour, déplacer et supprimer des blocs via des endpoints de ressource
  • plus tard, ajouter des blocs enfants via des endpoints de ressource
  • plus tard, gérer la navigation et les shared slots

Endpoints de ressource de la phase 1 :

GET /webadmin/api/sites
GET /webadmin/api/locales
GET /webadmin/api/page-layouts
GET /webadmin/api/block-types
GET /webadmin/api/content-contract
GET /webadmin/api/pages
GET /webadmin/api/pages/{page}
POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks
POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot
GET /webadmin/api/blocks
GET /webadmin/api/blocks/{block}
GET /webadmin/api/navigation-menus
GET /webadmin/api/navigation-menus/{navigationMenu}
POST /webadmin/api/navigation-menus
POST /webadmin/api/navigation-menus/{navigationMenu}/items
GET /webadmin/api/shared-slots
GET /webadmin/api/shared-slots/{sharedSlot}
POST /webadmin/api/shared-slots
POST /webadmin/api/shared-slots/{sharedSlot}/blocks

Content Validate / Apply API

Les endpoints content validate/apply traitent des plans de contenu complets en plusieurs étapes :

POST /webadmin/api/content/validate
POST /webadmin/api/content/apply

validate vérifie un plan de contenu complet et n'écrit rien. apply valide de nouveau le plan puis crée, de façon transactionnelle, la page en brouillon demandée, les éléments de navigation, les Shared Slots, les arbres de blocs des Shared Slots et les affectations de Shared Slots aux slots de page. Il peut également remplacer des slots nommés appartenant à la page sur une page en brouillon existante lorsque le plan utilise mode: replace_existing_draft_page et comporte un garde-fou optimiste. C'est utile pour les pages générées par IA, les gabarits, les pages de départ, les en-têtes/pieds de page partagés et les utilitaires de migration, où le CMS doit éviter le contenu créé à moitié.

Le corps de la requête peut toujours contenir un champ plan ou un autre payload structuré de plan de contenu. L'URL doit rester /content/validate et /content/apply.

Les deux modes sont nécessaires :

  • la Resource API expose aux outils internes le modèle de contenu et les contrats existants du CMS
  • la Content Validate / Apply API évite les écritures partielles lors de constructions de pages plus importantes

Remplacement de slots sur une page en brouillon existante

Le remplacement sur une page en brouillon existante reste dans le contrat validate/apply :

POST /webadmin/api/content/validate
POST /webadmin/api/content/apply

Utilisez mode: replace_existing_draft_page pour remplacer un ou plusieurs slots appartenant à la page sur une page en brouillon existante. L'opération exige content.validate pour la validation et content.apply pour l'application. Elle n'exige pas pages.delete, car ce n'est pas une opération générale de suppression de page.

Le path de Page Translation est l'URL publique canonique. Les nouveaux plans doivent utiliser des chemins tels que /contact, /features ou /docs/internal-content-api ; /p/... relève uniquement de la compatibilité héritée. Les chemins comportant des barres obliques sont normalisés segment par segment : /docs/internal-content-api/ devient donc /docs/internal-content-api et n'est pas réduit à docsinternal-content-api. Les zones de routes réservées telles que /webadmin, /webadmin/api, /cms, /search, /search.json, /contact-messages, /install et les routes d'authentification de l'hôte ne peuvent pas être créées comme chemins publics de page.

Exemple :

{
  "plan": {
    "mode": "replace_existing_draft_page",
    "site": "default",
    "locale": "en",
    "page": {
      "id": 9,
      "expected_path": "/contact",
      "status": "draft"
    },
    "replace_slots": {
      "main": [
        {
          "type": "plain_text",
          "translations": {
            "content": "Updated draft contact content."
          }
        }
      ]
    }
  }
}

Règles :

  • la page cible doit être au statut draft
  • expected_path ou expected_updated_at est obligatoire
  • expected_path utilise le chemin public canonique de Page Translation, pas un alias hérité /p/...
  • la page cible doit appartenir au site demandé et la langue (locale) doit être activée pour ce site
  • chaque slot doit exister sur la page et utiliser des blocs appartenant à la page
  • les slots adossés à des Shared Slots sont rejetés au lieu d'être vidés
  • seuls les blocs des replace_slots nommés sont supprimés
  • les anciens blocs sont supprimés et les nouveaux écrits dans une seule transaction
  • des révisions de page sont capturées avant et après l'application
  • aucune publication, récupération/import de médias, suppression large ou effacement des affectations de Shared Slot n'a lieu

Métadonnées de synchronisation de la source

Les plans de contenu peuvent conserver un objet source_sync limité et sans secret pour les flux de synchronisation de documentation IA/opérateur. Les réglages de page arbitraires sont rejetés. La forme acceptée est :

{
  "page": {
    "settings": {
      "source_sync": {
        "type": "markdown_documentation",
        "source_id": "webblocks-cms:docs/internal-content-api.md",
        "source_path": "docs/internal-content-api.md",
        "source_sha256": "64-character-lowercase-sha256",
        "managed_slots": ["main"],
        "last_synced_at": "2026-06-25T00:00:00Z"
      }
    }
  }
}

Apply enregistre ces métadonnées dans les réglages de la page, et les réponses de l'API de liste/détail des pages exposent les mêmes champs source_sync autorisés pour des rapprochements ultérieurs. N'y incluez pas de tokens, de valeurs d'environnement, de chemins absolus locaux ou serveur, ni d'autres secrets.

Endpoints de publication explicites

La publication est distincte de content apply et exige un token doté de content.publish.

POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks

POST /webadmin/api/pages/{page}/publish publie l'enregistrement de la page. Son payload par défaut ne concerne que la page :

{
  "include_page_owned_blocks": false
}

Règles :

  • omettre include_page_owned_blocks équivaut à false
  • include_page_owned_blocks: false ne publie que l'enregistrement de la page et laisse inchangés les blocs en brouillon ou en relecture
  • include_page_owned_blocks: true publie les blocs en brouillon et en relecture appartenant aux slots de page non partagés, y compris les blocs enfants imbriqués
  • les blocs déjà publiés restent inchangés
  • les slots adossés à des Shared Slots sont exclus et signalés dans la réponse
  • les champs de cascade de Shared Slot non pris en charge, tels que publish_shared_slots, include_shared_slot_blocks ou shared_slot_cascade, renvoient un 422 JSON
  • la réponse contient les métadonnées d'id/statut/chemin de la page, l'indication de l'inclusion ou non des blocs appartenant à la page, le nombre de blocs publiés, le récapitulatif des Shared Slots exclus et l'id de la révision de page

POST /webadmin/api/pages/{page}/publish-page-owned-blocks ne publie que les blocs non publiés appartenant à la page et ne modifie pas le statut du flux de travail de la page. Il utilise la même capacité content.publish et la même règle d'exclusion des Shared Slots.

Les outils d'IA/opérateur ne doivent pas supposer que publier la page rend public l'ensemble du contenu des blocs. N'utilisez include_page_owned_blocks: true que lorsque l'utilisateur a explicitement approuvé la publication de tous les blocs non publiés appartenant à cette page. Le contenu des Shared Slots doit être relu et publié séparément.

Endpoint du contrat de contenu

GET /webadmin/api/content-contract est un endpoint de découverte en lecture seule destiné aux outils d'IA/opérateur de confiance. Il renvoie le préfixe de l'API, les URL de validate/apply, le gabarit d'URL de prévisualisation d'administration, les indicateurs de sécurité, les URL de découverte, les modèles recommandés de construction de pages et les métadonnées assainies des contrats de bloc.

Cet endpoint relève du comportement générique du produit CMS. Il ne doit pas renvoyer de secrets propres à l'installation, de valeurs de token, de contenus Blade bruts, de chemins absolus du système de fichiers, de chemins serveur privés ni d'instructions propres à un site. Les lignes de contrat de bloc peuvent inclure le handle/slug, le libellé, la catégorie, le statut, la prise en charge des conteneurs et des enfants, les champs traduisibles, les champs de réglages partagés et le comportement racine du moteur de rendu public.

Les outils d'IA doivent appeler cet endpoint ou GET /webadmin/api/block-types avant de construire un plan et n'utiliser que les handles présents dans l'installation actuelle.

Le contrat de contact_form comprend des métadonnées de formulaire supplémentaires et sûres : schéma des réglages, champs traduits, endpoint public d'envoi POST /contact-messages, comportement CSRF requis dans le navigateur, règles de validation côté serveur, champ de contrôle anti-spam masqué et généré par le CMS, comportement générique de succès de ce champ, notes de classification/mise en quarantaine du spam, enregistrement avant notification, ordre de repli des destinataires, consignation sûre des échecs de notification et comportement de relecture de /webadmin/contact-messages. Le champ de contrôle est généré par le moteur de rendu, ne fait pas partie de la saisie normale du visiteur et ne doit pas être créé manuellement par l'API ni par les outils d'IA/opérateur. Les outils de page de contact doivent utiliser ce bloc natif plutôt que Trusted HTML, du balisage de formulaire brut ou des formulaires mailto:. L'ancien champ website ne fait plus partie du contrat public du Contact Form.

Le guide lisible par un humain AI Page Building Guide est livré dans les installations natives par paquet à l'emplacement vendor/fklavyenet/webblocks-cms/docs/ai-page-building-guide.md.

Périmètre de la phase 1

Endpoints de découverte

  • GET /webadmin/api
  • GET /webadmin/api/openapi.json
  • GET /webadmin/api/ai-guide
  • GET /webadmin/api/examples
  • GET /webadmin/api/examples/contact-page
  • GET /webadmin/api/examples/landing-page
  • GET /webadmin/api/sites
  • GET /webadmin/api/locales
  • GET /webadmin/api/page-layouts
  • GET /webadmin/api/block-types
  • GET /webadmin/api/content-contract

Endpoints des pages

  • GET /webadmin/api/pages
  • GET /webadmin/api/pages/{page}
  • POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot

Endpoints des blocs

  • GET /webadmin/api/blocks
  • GET /webadmin/api/blocks/{block}

Endpoints de navigation

  • GET /webadmin/api/navigation-menus
  • GET /webadmin/api/navigation-menus/{navigationMenu}
  • POST /webadmin/api/navigation-menus
  • POST /webadmin/api/navigation-menus/{navigationMenu}/items

Les menus de navigation utilisent le modèle existant du CMS navigation_items.menu_key. La phase 2A prend en charge les handles de menu livrés avec le CMS, tels que primary, footer, mobile, legal et docs ; elle n'ajoute pas de table de menus distincte. Créer un menu de navigation revient à créer un groupe de menu sûr, propre au site, avec des éléments initiaux facultatifs. L'opération refuse d'écraser un site/menu qui contient déjà des éléments.

Les URL des éléments de navigation peuvent être des chemins internes comme /, /about et /contact, ou des URL sûres en http/https. L'API rejette javascript:, data:, les URL relatives au protocole, les remontées de répertoire, les URL malformées, les cibles non prises en charge et les libellés vides. Les endpoints de navigation ne créent pas de pages, ne publient pas de pages, n'explorent pas les sites et ne récupèrent pas d'URL distantes.

Endpoints des Shared Slots

  • GET /webadmin/api/shared-slots
  • GET /webadmin/api/shared-slots/{sharedSlot}
  • POST /webadmin/api/shared-slots
  • POST /webadmin/api/shared-slots/{sharedSlot}/blocks

La création de Shared Slots est propre au site et refuse les handles en double au sein d'un même site. Les blocs de Shared Slot réutilisent le même écrivain de payload que les blocs appartenant à la page : le texte propre à chaque langue reste donc dans les lignes de traduction et les réglages partagés restent sur l'enregistrement du bloc / le chemin des réglages. L'import et l'affectation de médias restent hors de cette phase.

Affectation des slots de page

POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot

L'endpoint affecte à un slot de page existant un Shared Slot existant, actif, compatible et appartenant au même site. Il ne crée pas les pages ni les slots manquants. Il ne publie pas la page. Il refuse les Shared Slots d'un autre site, inactifs ou incompatibles. Il refuse également de changer un slot qui contient encore des blocs appartenant à la page, car la phase 2A ne supprime ni ne remplace ces blocs automatiquement.

Endpoints Content Validate / Apply

  • POST /webadmin/api/content/validate
  • POST /webadmin/api/content/apply

Sécurité de la phase 1

  • brouillons uniquement
  • aucune publication via content apply
  • aucun écrasement de contenu publié existant
  • aucun écrasement large de pages ou de blocs existants en dehors de mode: replace_existing_draft_page
  • aucune récupération distante
  • aucun téléchargement ni import de médias
  • pas encore de création de site
  • aucune suppression destructrice de page via content apply
  • aucune suppression destructrice de blocs en dehors du remplacement de slots de brouillon limité à la transaction
  • pas encore d'endpoints de mise à jour, de déplacement ou de suppression de ressources
  • aucune exigence de session navigateur, de formulaire ou de CSRF pour les écritures JSON par token Bearer
  • l'accès public non authentifié se limite à la réponse d'amorçage minimale de GET /webadmin/api

Forme des erreurs JSON

Les erreurs de l'API sont uniquement en JSON. Elles ne doivent pas rediriger vers la page de connexion, afficher des pages CSRF ni exposer de traces de pile. Champs courants :

{
  "ok": false,
  "code": "invalid_internal_api_token",
  "message": "Invalid internal API token.",
  "api_discovery_url": "/webadmin/api",
  "openapi_url": "/webadmin/api/openapi.json",
  "documentation_url": "/webadmin/api/ai-guide",
  "example_url": "/webadmin/api/examples/contact-page",
  "errors": []
}

Statuts attendus :

  • 401 pour les tokens manquants, invalides ou révoqués
  • 403 pour les capacités manquantes
  • 422 pour les erreurs de validation

Exemples de Resource API

Lister les pages

GET /webadmin/api/pages

Lire le détail d'une page

GET /webadmin/api/pages/{page}

Lister les blocs

GET /webadmin/api/blocks

Lire le détail d'un bloc

GET /webadmin/api/blocks/{block}

Exemple de Content Validate / Apply

Le même payload peut être envoyé à l'un ou l'autre endpoint :

POST /webadmin/api/content/validate
POST /webadmin/api/content/apply

Exemple de brouillon de page d'accueil marketing en anglais :

{
  "plan": {
    "site": "example-site",
    "locale": "en",
    "layout": "default",
    "page": {
      "title": "Acme Studio",
      "path": "/",
      "status": "draft"
    },
    "slots": {
      "main": [
        {
          "type": "hero",
          "translations": {
            "title": "Plan, build, and publish with confidence",
            "subtitle": "Structured content for modern teams",
            "content": "Create a draft homepage from a validated content plan."
          },
          "children": [
            {
              "type": "button_link",
              "translations": {
                "title": "Start planning"
              },
              "settings": {
                "url": "/contact",
                "variant": "primary"
              }
            }
          ]
        },
        {
          "type": "section",
          "children": [
            {
              "type": "container",
              "children": [
                {
                  "type": "grid",
                  "settings": {
                    "columns": 3
                  },
                  "children": [
                    {
                      "type": "card",
                      "children": [
                        {
                          "type": "card_body",
                          "children": [
                            {
                              "type": "plain_text",
                              "translations": {
                                "content": "Validate the whole draft before anything is written."
                              }
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        },
        {
          "type": "cta",
          "translations": {
            "title": "Ready to shape the next page?",
            "content": "Use structured plans for repeatable content creation."
          },
          "children": [
            {
              "type": "button_link",
              "translations": {
                "title": "Contact us"
              },
              "settings": {
                "url": "/contact",
                "variant": "primary"
              }
            }
          ]
        }
      ]
    }
  }
}

Règles de validation

  • le handle ou l'ID du site doit être résolu
  • la langue (locale) doit exister et être activée pour le site cible
  • le layout doit exister
  • un conflit de chemin empêche la création de la page
  • le type de bloc doit être publié et utilisable
  • la prise en charge des enfants doit respecter les contrats de bloc lorsqu'ils existent
  • le texte destiné aux utilisateurs appartient aux lignes de traduction
  • les réglages partagés restent partagés
  • les réglages inconnus non sûrs sont rejetés
  • les réglages inconnus inoffensifs peuvent déclencher un avertissement ou être ignorés de manière cohérente
  • apply valide de nouveau avant d'écrire
  • apply est transactionnel
  • Content apply continue de rejeter la publication, la création de site, l'import de médias, la récupération distante, les écrasements non pris en charge, les remplacements non pris en charge et les suppressions
  • la création de navigation et de Shared Slots est en création seule, sauf si une phase ultérieure ajoute des contrats de mutation explicites et sûrs pour les brouillons

Forme de la réponse

Les réponses doivent être un JSON prévisible :

{
  "ok": true,
  "writes": [],
  "data": {
    "page": {
      "id": 123,
      "title": "Product Overview",
      "status": "draft",
      "edit_url": "/webadmin/pages/123/edit"
    }
  },
  "normalized_plan": {},
  "warnings": [],
  "errors": []
}

Les erreurs de validation doivent inclure un chemin et un message :

{
  "ok": false,
  "writes": [],
  "data": null,
  "normalized_plan": {},
  "warnings": [
    {
      "path": "plan.slots.main.1.settings.theme",
      "message": "Unknown harmless setting ignored."
    }
  ],
  "errors": [
    {
      "path": "plan.page.path",
      "message": "A page already exists at this path for the selected site and locale."
    }
  ]
}

Incluez edit_url lorsque c'est utile pour les ressources CMS créées ou mises à jour.

Sections du plan de la phase 2A

Les plans de contenu peuvent inclure navigation_menus, shared_slots et page_slot_shared_slots aux côtés du plan pages/slots existant. validate n'écrit rien. apply écrit toutes les sections valides dans une seule transaction et annule l'ensemble du plan dès qu'une section ultérieure échoue.

{
  "plan": {
    "site": "default",
    "locale": "en",
    "layout": "default",
    "page": {
      "title": "Homepage Draft",
      "path": "/",
      "status": "draft"
    },
    "slots": {
      "main": []
    },
    "navigation_menus": [
      {
        "handle": "primary",
        "label": "Primary Navigation",
        "items": [
          {
            "label": "Home",
            "url": "/",
            "target": "_self",
            "sort_order": 10
          }
        ]
      }
    ],
    "shared_slots": [
      {
        "handle": "site-header",
        "label": "Site Header",
        "slot": "header",
        "blocks": []
      }
    ],
    "page_slot_shared_slots": [
      {
        "page": "created",
        "slot": "header",
        "shared_slot": "site-header"
      }
    ]
  }
}

page_slot_shared_slots[].page peut désigner la page créée par le même plan en utilisant created, ou l'ID d'une page existante. shared_slot peut désigner un Shared Slot créé plus tôt dans le même plan ou le handle d'un Shared Slot existant du même site.

Phases à venir

Phase 2B

  • endpoints optionnels de mise à jour/déplacement sûrs pour les brouillons, pour la navigation et les blocs de Shared Slot
  • contrats explicites de vidage/remplacement sûrs là où c'est nécessaire
  • assistants plus poussés pour construire des en-têtes/navbars, uniquement s'ils restent un comportement générique du CMS

Phase 3

  • endpoints de ressource pour des modifications directes de pages/blocs sûres pour les brouillons, là où c'est nécessaire
  • mises à jour contrôlées des brouillons ou remplacement du contenu en brouillon
  • ressources de page
  • médias uniquement par ID de média existant

Phase 4

  • transitions de flux de travail explicites supplémentaires au-delà de la publication, lorsqu'elles disposent d'une conception et de permissions distinctes

Conseils d'utilisation avec l'IA

  • découvrez d'abord les sites, les langues (locales), les layouts et les types de bloc
  • validez avant d'appliquer
  • créez du contenu en brouillon
  • privilégiez les blocs structurés de docs/public-block-render-markup.md
  • évitez Safe HTML, sauf comme solution de repli relue
  • rédigez le texte public généré dans la langue cible, par exemple l'anglais pour une page d'accueil en anglais

Limites

  • aucune intégration OpenAI ou LLM dans le cœur du CMS
  • aucun crawl ni récupération de contenu
  • aucun remplacement arbitraire de l'import/export
  • aucune publication automatique
  • aucune suppression destructrice en phase 1
  • aucune hypothèse sur la route /admin de l'hôte
  • aucun usage du préfixe de route /cms
  • aucun code d'exécution propre à QuizTem ; la génération de la page d'accueil de QuizTem est un cas d'usage ultérieur de cette API CMS générique