Internal Content API

Accesso AI delegato dall'utente

CMS possono creare token API personali in scadenza dal proprio profilo. Un token personale si autentica come utente proprietario ed è autorizzato dall'intersezione delle funzionalità del token, dei siti selezionati, del ruolo attuale del proprietario, delle assegnazioni attuali del sito e del normale flusso di lavoro del contenuto. Diventa immediatamente inutilizzabile quando il proprietario è inattivo o non ha più accesso al CMS.

I token personali sono destinati a contenuti, navigazione, Shared Slot, media, coinvolgimento e flussi di lavoro di bozze. Le operazioni a livello di installazione rimangono solo token di sistema. Le richieste di scrittura personali che creano o selezionano contenuto devono fornire il sito di destinazione anziché fare affidamento sul fallback del sito primario dell'installazione. L'attività dell'API continua a registrare il token, mentre gli attori del controllo della pagina e della revisione si risolvono nell'utente delegante.

Eciascun token personale può anche contenere una lista consentita opzionale di indirizzi IPv4/IPv6 esatti o reti CIDR e il proprio limite massimo di 30, 60, 120 o 300 richieste al minuto. Un elenco di reti vuoto consente qualsiasi indirizzo client, preservando il comportamento del token esistente; i token senza un limite memorizzato utilizzano 60 richieste al minuto. Questi vincoli attivi sono inclusi nel rilevamento autenticato in token.network_policy e un limite specifico del token potrebbe pertanto essere inferiore alla limitazione dell'API a livello di installazione.

Scopo

Internal Content API è un CMS sicuro API per strumenti operatore e IA affidabili. Consente a questi strumenti di ispezionare i contratti di contenuto CMS, creare contenuti in bozza, sostituire specifici slot di proprietà della pagina su pagine bozza esistenti, eseguire operazioni di pubblicazione esplicite tramite JSON strutturato e richiedere istantanee di rendering dell'amministratore autorizzato per il QA visivo senza accedere, eseguire lo scraping o automatizzare l'interfaccia utente di amministrazione del browser.

La fase 1 è implementata come API non pubblico, protetto da token, solo JSON per il rilevamento di contenuto di sola lettura e la creazione di bozze di pagine tramite piani di contenuto convalidati. La fase 2A aggiunge basi sicure per i menu di navigazione, Shared Slots e l'assegnazione esplicita dello slot di pagina Shared Slot. La Fase 2B aggiunge una sostituzione controllata di sola bozza per il contenuto dell'area di proprietà della pagina sulle pagine esistenti. Gli endpoint di pubblicazione sono espliciti e richiedono content.publish; il contenuto applicato rimane prima la bozza e non viene pubblicato. Lo API rimane intenzionalmente limitato: nessun recupero remoto, nessuna eliminazione di pagine estese tramite il contenuto applicato, nessuna sostituzione degli slot supportati da Shared Slot e nessuna pubblicazione a cascata Shared Slot.

Posizionamento del prodotto

La Internal Content API è:

  • un'API del CMS interna/per operatori
  • protetta da token
  • non pubblica
  • non un'API di delivery per CMS headless
  • non un sostituto dei permessi di amministrazione
  • non un sostituto di import/export
  • non un'integrazione con un fornitore di IA

Il core del CMS dovrebbe essere il proprietario di questa API perché opera su concetti di contenuto del core: siti, pagine, layout, slot, blocchi, traduzioni, navigazione e shared slot. Gli strumenti di IA o di operatore possono chiamare l'API, ma il core del CMS non deve incorporare logiche di integrazione con OpenAI, LLM, crawler o fornitori specifici.

Prefisso di rotta

Il prefisso canonico è:

/webadmin/api

Ciò mantiene API all'interno dei limiti dell'amministratore CMS mentre utilizza un segmento API conciso e familiare. Gli endpoint in stile risorsa dovrebbero risiedere direttamente sotto questo prefisso, come /webadmin/api/pages e /webadmin/api/blocks.

Prima di pianificare il contenuto, leggere il pacchetto CMS Inventory con GET /webadmin/api/inventory. È il contratto di progettazione e creazione per blocco ed è il primo documento che un'intelligenza artificiale dovrebbe leggere. Il blocco html è riservato agli esseri umani: rimane leggibile tramite API, ma ogni mutazione API che lo tocca viene rifiutata con 422 e il codice stabile block_type_not_api_writable, e nessuna funzionalità lo sovrascrive. Per un blocco application, scoprire prima una definizione pronta e il relativo schema di impostazioni tramite GET /webadmin/api/applications; Le scritture API possono fare riferimento ad applicazioni registrate ma non possono introdurre codice eseguibile o percorsi di file.

API il rilevamento inizia alle:

GET /webadmin/api

I chiamanti non autenticati ricevono solo il bootstrap di sicurezza pubblica JSON. I chiamanti autenticati ricevono metadati sicuri della versione del prodotto oltre a collegamenti a OpenAPI, guida AI, contratto di contenuto, esempi, convalida/applicazione di contenuto, pagine, blocchi, contenuti multimediali, navigazione e Shared Slots. Gli strumenti IA/operatore esterni dovrebbero iniziare da questa risposta di rilevamento in tempo reale invece di leggere il repository CMS o i documenti del pacchetto locale.

Utilizzo delle operazioni sui contenuti basate sul piano:

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

Scelte di rotta da evitare:

  • /webadmin/internal-api, perché inutilmente prolisso
  • /webadmin/api/content-plans/..., perché content-plans è troppo tecnico e ristretto per il contratto dell'URL
  • collocare ogni risorsa sotto /webadmin/api/content/..., perché le API di risorsa devono restare chiare e dirette
  • /admin, perché il CMS non deve presumere che il percorso /admin del prodotto ospite gli appartenga
  • /cms, perché /cms resta riservato ai soli asset statici del CMS

Autenticazione

L'API usa l'autenticazione con token Bearer:

Authorization: Bearer <token>

Il CMS ha due superfici token. Editor, amministratori del sito e super amministratori creano token API personali da Profile -> Personal API Tokens; tali token agiscono come proprietari entro i limiti di ruolo live, sito, flusso di lavoro, rete e capacità. I super amministratori creano token di sistema API da System -> API Tokens per l'automazione a livello di installazione esplicitamente autorizzata. Il CMS memorizza solo un hash SHA-256 più un'anteprima sicura nella tabella del database cms_api_tokens. Il token semplice viene mostrato una volta immediatamente dopo la creazione e non viene mai più mostrato.

Il pannello dei token monouso fornisce controlli di copia sia per il token completo che per l'esempio .env locale generato. Il feedback sulla copia viene annunciato in modo accessibile e l'implementazione del browser include un fallback per ambienti senza i moderni Appunti API.

Token creati con il vecchio set di funzionalità di creazione di pagine predefinite vengono considerati idonei per la funzionalità admin.render di sola lettura in fase di runtime, quindi gli strumenti dell'operatore attendibile possono utilizzare snapshot QA visivi dell'amministratore consentiti dopo l'aggiornamento senza ruotare il token. I token personalizzati ristretti che non includono il precedente set predefinito rimangono limitati.

Entrambe le schermate dei token includono un'azione cronologica per ciascun token. Apre una finestra modale WebBlocks UI con gli ultimi 10 record di attività API per quel token. I record delle attività sono intenzionalmente piccoli: ora della richiesta, stato, metodo, percorso senza stringa di query, nome del percorso, capacità richiesta quando è stata valutata una protezione di capacità, IP e un breve valore dell'agente utente. Il CMS non archivia corpi di richiesta, stringhe di query, corpi di risposta, valori di token di connessione, hash di token o anteprime di token nelle righe di attività. Le righe di attività meno recenti vengono eliminate automaticamente in modo che ciascun token conservi solo gli ultimi 10 record.

Gli utenti possono modificare, revocare ed eliminare i propri token personali; I super amministratori gestiscono i token di sistema. La modifica modifica i metadati della policy senza rivelarne il segreto. La revoca disabilita immediatamente l'accesso API mantenendo la riga di controllo. L'eliminazione di un token ne rimuove permanentemente lo stesso e la relativa cronologia delle attività.

Gli strumenti dell'operatore e dell'intelligenza artificiale locale devono archiviare il token generato in un archivio segreto dell'operatore attendibile.

Utilizzare l'URL di base Internal Content API nella configurazione dell'operatore locale:

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

Il runtime CMS non richiede WEBBLOCKS_CMS_INTERNAL_API_TOKEN.

Regole di autenticazione:

  • I token mancanti, errati o revocati vengono restituiti JSON 401
  • I token revocati smettono di funzionare immediatamente
  • I token
  • non devono mai essere stampati in registri, diagnostica, rapporti di supporto, test o esempi di documentazione
  • Il confronto dei token deve utilizzare un confronto a tempo costante
  • Le richieste API riuscite aggiornano last_used_at e last_used_ip
  • Le richieste API riuscite memorizzano anche un agente utente troncato per il contesto di controllo dell'operatore
  • risposte delle risorse normali e tutti gli errori sono JSON; Le rotte QA visive consentite possono restituire HTML diretto solo quando il chiamante richiede esplicitamente un formato HTML

Esempio di richiesta:

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

Capability

I proprietari di token scelgono le funzionalità durante la creazione o la modifica di un token personale; I super amministratori fanno lo stesso per i token di sistema. La modifica non espone né ruota il segreto. Un modulo token personale mostra solo le funzionalità che il ruolo attuale del proprietario può delegare e ogni richiesta ricontrolla quel ruolo attivo. L'individuazione espone le funzionalità effettive senza restituire il valore del token, l'hash del token o l'anteprima del token. I token standard per la creazione di pagine utilizzano queste funzionalità:

  • content.read
  • content.validate
  • content.apply
  • navigation.write
  • shared-slots.write
  • media.read
  • site-settings.write

Le funzionalità avanzate sono opzioni separate e non sono selezionate per impostazione predefinita:

Gli endpoint

  • navigation.delete
  • shared-slots.delete
  • domains.write
  • domains.delete
  • site-assets.read
  • site-assets.write
  • engagement.read
  • engagement.moderate
  • plugins.read
  • plugins.install
  • plugins.manage
  • plugins.setup
  • plugins.uninstall
  • commerce.read
  • commerce.products.write
  • commerce.orders.read
  • media.write
  • media.upload
  • media.replace
  • media.move
  • media.delete
  • content.publish
  • pages.delete
  • content.blocks.delete
  • backups.create
  • page-assets.write

Write controllano la funzionalità rilevante lato server. Le funzionalità mancanti restituiscono JSON 403 con le indicazioni api_discovery_url, openapi_url, documentation_url e example_url. I normali token di creazione di pagine non devono includere funzionalità distruttive come l'eliminazione della navigazione, l'eliminazione di Shared Slot, la pubblicazione di contenuti, l'installazione/gestione/configurazione/disinstallazione di plug-in o l'eliminazione di pagine. La lettura di commenti/feedback di valutazione richiede engagement.read esplicito; la modifica dello stato del commento richiede engagement.moderate esplicito. L'automazione del ciclo di vita del plug-in richiede funzionalità di plug-in esplicite e l'accesso al prodotto/ordine commerciale WebBlocks API richiede funzionalità di commercio esplicite.

Limite di velocità

Ogni instradamento /webadmin/api e gli instradamenti /admin-api legacy condividono due budget di richiesta. Il budget per IP client e token è impostato per impostazione predefinita su 120 richieste al minuto (CMS_INTERNAL_API_RATE_LIMIT_PER_MINUTE). Per impostazione predefinita, un backstop IP indipendente è di 300 richieste al minuto su tutti i token forniti e sui percorsi API (CMS_INTERNAL_API_IP_RATE_LIMIT_PER_MINUTE), inclusi i tentativi di token non validi. La rotazione dei token non reimposta questo backstop. Il superamento di uno dei budget restituisce 429 con un'intestazione Retry-After. I valori di configurazione non positivi tornano ai valori predefiniti.

Leggi i budget in tempo reale da x-rate-limit su GET /webadmin/api/openapi.json: requests_per_minute è il budget token e IP e ip_requests_per_minute è il budget IP indipendente. I client che condividono un IP devono coordinare il volume di richieste combinato.

Un Super amministratore attivo può sovrascrivere entrambi i budget in Sistema → Impostazioni → Sicurezza. I valori del pannello supportati da database hanno la precedenza sulla configurazione di installazione e si applicano alle richieste successive senza reimpostare i contatori esistenti. Utilizza impostazioni predefinite di installazione rimuove le sostituzioni di sicurezza e ripristina i budget configurati. Il salvataggio o il ripristino non modifica .env o le impostazioni del server. I budget delle richieste accettano numeri interi positivi fino a 1.000.000. I limiti specifici del token personale rimangono limiti aggiuntivi; modificarli non modifica i budget API condivisi.

I livelli di hosting, proxy o CDN davanti al sito possono imporre un limite inferiore rispetto a quello del CMS, quindi un client in blocco come un passaggio di traduzione dell'intero sito dovrebbe procedere da solo e tornare indietro su 429 invece di riprovare immediatamente.

I token personali prevedono inoltre un tetto configurabile di 30, 60, 120 o 300 richieste al minuto; i token personali esistenti senza un valore salvato utilizzano 60. Possono anche limitare l'accesso a indirizzi IPv4/IPv6 esatti o reti CIDR. Il rilevamento autenticato riporta queste impostazioni in token.network_policy. L'IP del client risolto di Laravel è autorevole, quindi gli host dietro un proxy inverso o una CDN devono fidarsi solo dei propri indirizzi proxy reali e delle intestazioni inoltrate prima di fare affidamento sulla lista consentita.

Modello dell'API

L'API ha due modalità complementari.

API delle risorse

Gli endpoint di risorsa rispecchiano le singole operazioni equivalenti a quelle dell'amministrazione:

  • elencare e leggere le pagine
  • elencare e leggere i blocchi
  • elencare siti, lingue (locale), layout e tipi di blocco
  • in seguito, creare o aggiornare direttamente risorse di pagina in bozza
  • in seguito, elencare o garantire gli slot di pagina
  • in seguito, aggiungere, aggiornare, spostare ed eliminare blocchi tramite endpoint di risorsa
  • in seguito, aggiungere blocchi figli tramite endpoint di risorsa
  • in seguito, gestire navigazione e shared slot

Endpoint di risorsa della fase 1:

GET /webadmin/api/sites
GET /webadmin/api/locales
GET /webadmin/api/locale-options
POST /webadmin/api/locales
PATCH /webadmin/api/locales/{locale}
GET /webadmin/api/page-layouts
GET /webadmin/api/block-types
GET /webadmin/api/content-contract
GET /webadmin/api/pages
GET /webadmin/api/pages/{page}
GET /webadmin/api/pages/{page}/versions
GET /webadmin/api/pages/{page}/versions/{version}
POST /webadmin/api/pages/{page}/versions/{version}/candidate
POST /webadmin/api/pages/{page}/version-candidates/{candidate}/apply
DELETE /webadmin/api/pages/{page}/version-candidates/{candidate}
POST /webadmin/api/pages/{page}/publish
POST /webadmin/api/pages/{page}/publish-page-owned-blocks
POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot
PUT /webadmin/api/pages/{page}/slots/{slot}/source
GET /webadmin/api/pages/{page}/assets
POST /webadmin/api/pages/{page}/assets/{type}
PATCH /webadmin/api/pages/{page}/assets/{pageAsset}
DELETE /webadmin/api/pages/{page}/assets/{pageAsset}
GET /webadmin/api/media
POST /webadmin/api/media/fetch
GET /webadmin/api/blocks
GET /webadmin/api/blocks/{block}
PATCH /webadmin/api/blocks/{block}
POST /webadmin/api/pages/{page}/slots/{slot}/blocks
PATCH /webadmin/api/pages/{page}/slots/{slot}/blocks/reorder
DELETE /webadmin/api/pages/{page}/slots/{slot}/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
PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/reorder
DELETE /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
GET /webadmin/api/shared-slots
GET /webadmin/api/shared-slots/{sharedSlot}
POST /webadmin/api/shared-slots
POST /webadmin/api/shared-slots/{sharedSlot}/blocks
PATCH /webadmin/api/shared-slots/{sharedSlot}/blocks/reorder
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks/{block}
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks
GET /webadmin/api/plugins
POST /webadmin/api/plugins/install
POST /webadmin/api/plugins/{plugin}/enable
POST /webadmin/api/plugins/{plugin}/setup
POST /webadmin/api/plugins/{plugin}/disable
DELETE /webadmin/api/plugins/{plugin}
GET /webadmin/api/commerce/products
POST /webadmin/api/commerce/products
PATCH /webadmin/api/commerce/products/{product}
GET /webadmin/api/commerce/orders
GET /webadmin/api/commerce/orders/{order}
GET /webadmin/api/sites/{site}/assets/css
PUT /webadmin/api/sites/{site}/assets/css

GET /webadmin/api/locale-options restituisce il catalogo di selezione delle impostazioni internazionali della lingua standard curata come elenco locale_options semplice. Gli strumenti API dovrebbero scegliere un locale_option restituito quando si crea una lingua locale normale invece di inventare stringhe code e name.

POST /webadmin/api/locales e PATCH /webadmin/api/locales/{locale} richiedono site-settings.write e accettano solo campi con impostazioni locali sicure: locale_option, code, name, is_default e is_enabled. L'invio di locale_option copia il codice canonico e il nome inglese dal catalogo standard; i modelli diretti code e name rimangono disponibili per varianti nazionali controllate o casi personalizzati/operatore. L'impostazione di is_default=true forza l'abilitazione della locale e abbassa qualsiasi impostazione predefinita precedente tramite la normale invariante della locale CMS. Gli strumenti di migrazione dovrebbero applicare una patch a un ID locale esistente quando correggono un errore di installazione relativo alla sola lingua, ad esempio la modifica di una nuova installazione tedesca con una sola locale da en a de, in modo che le relazioni esistenti con la pagina, il blocco e la locale del sito mantengano i loro ID.

API di convalida/applicazione contenuto

Gli endpoint content validate/apply gestiscono piani di contenuto completi in più passaggi:

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

validate verifica un piano di contenuto completo e non scrive nulla. apply valida di nuovo il piano e poi crea in modo transazionale la pagina in bozza richiesta, le voci di navigazione, gli Shared Slot, gli alberi di blocchi degli Shared Slot e le assegnazioni di Shared Slot agli slot di pagina. Può inoltre sostituire slot specifici di proprietà della pagina su una pagina in bozza esistente quando il piano usa mode: replace_existing_draft_page e include una protezione ottimistica. È utile per pagine generate dall'IA, template, pagine iniziali, header/footer condivisi e strumenti di migrazione, casi in cui il CMS deve evitare contenuti creati a metà.

Il corpo della richiesta può ancora contenere un campo plan o un altro payload strutturato di piano di contenuto. L'URL deve restare /content/validate e /content/apply.

Servono entrambe le modalità:

  • la Resource API espone agli strumenti interni il modello di contenuto e i contratti già esistenti del CMS
  • la Content Validate / Apply API evita scritture parziali durante costruzioni di pagina più ampie

Applica punto di ripristino

POST /content/apply accetta un flag create_restore_point: true di livello superiore opzionale. Quando impostato, il CMS esegue un backup completo del sistema (database più caricamenti) come punto di ripristino prima di applicare il piano, in modo che un operatore possa eseguire il rollback da System -> Backups se un'applicazione generata dall'intelligenza artificiale va male.

{
  "create_restore_point": true,
  "plan": { "mode": "create_draft_page", "page": { "...": "..." } }
}

Regole:

  • richiede la funzionalità dedicata backups.create, che non fa parte del set di creazione della pagina predefinito; senza di essa la richiesta restituisce JSON 403
  • il piano viene convalidato per primo, quindi un piano non valido restituisce 422 senza creare un backup sprecato
  • se non è possibile creare il backup l'applicazione viene interrotta e ritorna JSON 409; il contenuto non viene mai applicato senza la rete di sicurezza richiesta
  • in caso di successo, la risposta di applicazione include un oggetto restore_point con il backup id, type (content_apply), label, status e created_at
  • il backup è completo e sincrono, quindi aggiunge una notevole latenza; utilizzarlo per applicazioni estese o distruttive, non per l'automazione ad alta frequenza

API espone intenzionalmente solo la creazione di punti di ripristino. Il ripristino, il download e l'eliminazione dei backup rimangono nell'interfaccia utente di amministrazione dell'operatore e non fanno parte del token API.

API dei plugin e di Commerce

Gli strumenti operatore affidabili possono gestire i plug-in installati manualmente tramite endpoint del ciclo di vita espliciti:

GET /webadmin/api/plugins
POST /webadmin/api/plugins/install
POST /webadmin/api/plugins/{plugin}/enable
POST /webadmin/api/plugins/{plugin}/setup
POST /webadmin/api/plugins/{plugin}/disable
DELETE /webadmin/api/plugins/{plugin}
GET /webadmin/api/plugins/catalog
GET /webadmin/api/plugins/catalog/{plugin}
POST /webadmin/api/plugins/catalog/{plugin}/install
POST /webadmin/api/plugins/catalog/{plugin}/update

Questi endpoint richiedono rispettivamente plugins.read, plugins.install, plugins.manage, plugins.setup o plugins.uninstall. Funzionano con l'autenticazione della portante e non richiedono una sessione del browser autenticata. L'endpoint di installazione manuale accetta un artefatto ZIP del plug-in convalidato. Le richieste di elenco/dettagli del catalogo richiedono plugins.read; l'installazione e l'aggiornamento del catalogo richiedono plugins.install e il riutilizzo del client del catalogo CMS, controlli di compatibilità, convalida delle dimensioni degli artefatti/ZIP e verifica SHA-256. Un aggiornamento del catalogo deve essere più recente della versione installata e ripristina il precedente stato abilitato del plug-in solo dopo che la convalida dell'avvio e la configurazione del database hanno esito positivo. Entrambi i percorsi di installazione mantengono disabilitato il plug-in appena installato per impostazione predefinita. Dal momento che CMS 1.92.0, l'installazione, gli aggiornamenti e l'attivazione applicano automaticamente le modifiche del database del plug-in richieste. Una configurazione non riuscita lascia il plug-in disabilitato con un'azione di riprova esplicita. Pannello/API abilita e configura il rifiuto dei plugin incompatibili con HTTP 409 e plugin_incompatible prima di cambiare stato. CMS 1.94.0 aggiunge un controllo di avvio isolato obbligatorio, pacchetti conservati, quarantena di runtime e /webadmin/plugin-recovery; vedere Sistema di plug-in per le condizioni di ripristino. La disinstallazione è limitata ai plugin disabilitati caricati manualmente e conserva le tabelle di proprietà dei plugin.

Quando WebBlocks Commerce è abilitato e pronto per l'installazione, gli strumenti affidabili possono creare/elencare prodotti e leggere ordini:

GET /webadmin/api/commerce/products
POST /webadmin/api/commerce/products
PATCH /webadmin/api/commerce/products/{product}
GET /webadmin/api/commerce/orders
GET /webadmin/api/commerce/orders/{order}

Le letture dei prodotti Commerce richiedono commerce.read, le scritture dei prodotti richiedono commerce.products.write e le letture degli ordini richiedono commerce.orders.read. Se il plug-in è disabilitato o le migrazioni di configurazione non sono state eseguite, gli endpoint Commerce restituiscono JSON 409 con indicazioni di configurazione anziché un errore di database non elaborato.

Il blocco webblocks-commerce-buy-button di proprietà del plugin è rilevabile da GET /webadmin/api/block-types e GET /webadmin/api/content-contract solo mentre il plugin è abilitato. Le sue impostazioni richiedono settings.commerce_product_id da GET /webadmin/api/commerce/products; convalidare/applicare rifiuti ID prodotto mancanti, sconosciuti o inattivi. Il pagamento rimane nel flusso pubblico Commerce/PayPal. Il CMS API crea prodotti e blocchi di pagine, ma non raccoglie i dati delle carte né avvia un flusso di inserimento carte.

Aggiornamenti del campo nativo del blocco esistente

Utilizzare la convalida/applicazione del contenuto per creare una pagina intera in un'unica transazione. Per modifiche bozza incrementali, utilizzare la topologia blocco pagina API per aggiungere, riordinare o eliminare singoli blocchi di proprietà della pagina. Utilizza l'endpoint di aggiornamento del blocco esistente solo quando il blocco esiste già e la modifica è mappata in un campo nativo sicuro:

GET /webadmin/api/media?kind=image
PATCH /webadmin/api/blocks/{block}

L'endpoint richiede content.apply. Se il blocco fa parte di un albero sorgente Shared Slot, il token deve avere anche shared-slots.write.

I campi supportati sono intenzionalmente limitati:

  • media_id o asset_id per navbar-brand e sidebar-brand supporto logo
  • media_id o asset_id per hero, section, card, cta e content_header supporti di sfondo
  • settings.url
  • settings.target
  • settings.aria_label
  • settings.background_position
  • settings.background_overlay
  • settings.show_search per header-actions
  • settings.show_mode_toggle per header-actions
  • settings.show_accent_toggle per header-actions
  • settings.show_language_switcher per header-actions
  • traduzioni di testo come title e subtitle
  • Traduzioni di blocchi di immagini tramite translations.image.alt_text, translations.image.caption o le scorciatoie translations.alt_text e translations.caption
  • Visualizzatore galleria di immagini raggruppamento tramite settings.viewer_enabled e uno settings.viewer_group minuscolo; abilitato, scollegato I blocchi di immagini che condividono un gruppo vengono visualizzati in un visualizzatore di gallerie CMS esistente rimanendo posizionati in modo indipendente
  • Traduzioni dei moduli di contatto tramite translations.contact_form.submit_label e translations.contact_form.success_message, o gli stessi nomi della abbreviazione, accanto a title e content
  • url
  • variant

I campi tradotti vengono scritti nella famiglia di traduzione a cui appartiene il tipo di blocco, per la locale nella richiesta (la locale predefinita del sito quando locale viene omesso):

text

Campo Dettagli
Famiglia text
Tipi di blocco , hero, rich-text, colonne, cta e la maggior parte dei blocchi content
Campi Intestazione title, eyebrow, subtitle, content, meta

button

Campo Dettagli
Famiglia button
Tipi di blocco button
Campi Intestazione title

image

Campo Dettagli
Famiglia image
Tipi di blocco image
Campi Intestazione caption, alt_text (accettato anche come title, subtitle)

contact_form

Campo Dettagli
Famiglia contact_form
Tipi di blocco contact_form
Campi Intestazione title, content, submit_label, success_message

A che la famiglia non possiede viene rifiutato con 422 e codice unsupported_block_translation_fields, e un tipo di blocco senza famiglia di traduzione rifiuta translations completamente con unsupported_block_translations — nessuno dei due viene scritto nella tabella di testo, dove nulla lo leggerebbe. Una lingua non abilitata dal sito del blocco viene rifiutata con invalid_block_translation_locale. Le righe memorizzate vengono restituite in block.translations, codificate per famiglia.

Per i blocchi Immagine, una stringa esplicitamente vuota o null cancella caption o alt_text della locale selezionata; gli alias title e subtitle hanno lo stesso comportamento. I campi omessi mantengono i valori memorizzati. La cancellazione del testo dell'immagine editoriale preserva altre lingue, riferimenti multimediali e associazioni dinamiche. Una didascalia editoriale vuota non produce alcuna didascalia a meno che una rilegatura dinamica non ne fornisca una; il fallback Media/origine dinamica esistente per il testo alternativo rimane in vigore.

A submit_label e success_message del modulo di contatto sono traduzioni, non impostazioni: sono l'unico modo per localizzare il pulsante del modulo e il testo di conferma e non possono essere impostati tramite settings.

L'endpoint rifiuta i campi di topologia e implementazione del database come parent_id, slot_type_id, block_type_id, type, sort_order e children. Rifiuta inoltre HTML non elaborato, URL multimediali remoti e URL di origine. I media esistenti possono essere selezionati dalla Libreria multimediale CMS, ma questo API non importa o scarica nuovi media remoti.

Esempio:

{
  "locale": "en",
  "media_id": 12,
  "settings": {
    "url": "/",
    "target": "_self",
    "aria_label": "WebBlocks CMS home"
  },
  "translations": {
    "title": "WebBlocks CMS",
    "subtitle": "A modern block-based CMS."
  }
}

Per un blocco immagine esistente, aggiornare la riga di traduzione dell'immagine di proprietà locale con:

{
  "locale": "en",
  "translations": {
    "image": {
      "alt_text": "Dashboard-style ecosystem panel",
      "caption": "Homepage ecosystem panel"
    }
  }
}

Topologia blocco pagina API

Per la modifica incrementale della bozza della pagina, la topologia dei blocchi di proprietà della pagina può essere modificata un'operazione alla volta senza inviare un piano di contenuto completo:

POST /webadmin/api/pages/{page}/slots/{slot}/blocks
PATCH /webadmin/api/pages/{page}/slots/{slot}/blocks/reorder
DELETE /webadmin/api/pages/{page}/slots/{slot}/blocks/{block}

{slot} è uno slug di slot di proprietà della pagina. Questi endpoint sono intenzionalmente protetti dalle bozze e stretti:

  • operano solo sulle bozze; una pagina non bozza restituisce JSON 409 con codice page_not_draft. Utilizza contenuto applica aggiornamenti graduali per le pagine pubblicate.
  • funzionano solo sugli slot di proprietà della pagina; uno slot supportato da Shared Slot restituisce JSON 422. Utilizza gli endpoint Shared Slot per il contenuto Shared Slot.
  • Uno slot di pagina sconosciuto restituisce JSON 404.

POST .../blocks aggiunge un blocco utilizzando lo stesso payload di blocco normalizzato applicato al contenuto (type, settings, translations e children nidificato). I nuovi blocchi vengono creati con lo stato draft e aggiunti alla fine dello slot. Passa parent_id da aggiungere sotto un blocco contenitore esistente nello stesso slot; il genitore deve accettare i figli. La creazione e il riordino richiedono content.apply.

PATCH .../blocks/reorder rinumera un gruppo di pari livello. L'array blocks deve contenere ogni ID fratello per un singolo gruppo padre esattamente una volta, nell'ordine desiderato; il genitore è derivato dai blocchi inviati. L'invio di un gruppo parziale restituisce JSON 422.

DELETE .../blocks/{block} rimuove il blocco e il suo intero sottoalbero e restituisce deleted_blocks_count. L'eliminazione richiede la funzionalità dedicata content.blocks.delete, che non fa parte del set di funzionalità di creazione di pagine predefinito. I blocchi di origine Shared Slot non possono essere eliminati tramite questo endpoint.

Ogni scrittura acquisisce una revisione della pagina in modo che le bozze delle modifiche rimangano reversibili.

Azioni Hero e CTA

hero e cta sono contenitori ordinari i cui pulsanti di azione sono semplici figli button_link: dichiarali sotto children come qualsiasi altro blocco nidificato. Rimangono due campi di blocco opzionali come abbreviazione per il caso comune a uno o due pulsanti:

{
  "type": "hero",
  "translations": { "title": "Welcome" },
  "primary_cta": { "label": "Get started", "url": "/signup" },
  "secondary_cta": { "label": "Docs", "url": "https://example.com/docs" }
}

Entrambi i campi accettano un oggetto con label obbligatorio e url obbligatorio oppure null per lasciare l'azione non impostata. Gli URL devono essere un percorso interno sicuro o un URL http(s). La scorciatoia scrive i primi due figli button_link, quindi il risultato è indistinguibile dai pulsanti che un editor aggiunge manualmente. Dichiarare esplicitamente i figli è la forma canonica e l'unico modo per creare più di due pulsanti. L'invio di primary_cta o secondary_cta su qualsiasi altro tipo di blocco viene rifiutato.

I campi funzionano ovunque sia accettato un payload di blocco: convalida contenuto/applica piani, POST /pages/{page}/slots/{slot}/blocks e POST /shared-slots/{sharedSlot}/blocks.

Rendering della pagina API

Revisione della versione della pagina e ripristino dei candidati

Il ripristino della pagina utilizza un flusso di lavoro di ispezione-anteprima-applicazione. Non esiste un endpoint di ripristino diretto.

  • GET /webadmin/api/pages/{page}/versions elenca le versioni salvate con lo stato della pagina, i campi di controllo e un riepilogo delle modifiche rispetto alla versione precedente. GET .../versions/{version} restituisce il risultato completo del confronto e dell'integrità di riferimento. Entrambi richiedono content.read.
  • POST .../versions/{version}/candidate richiede content.apply. Crea una bozza candidata privata dall'istantanea e restituisce l'URL di anteprima del browser. La pagina di origine non viene modificata.
  • POST .../version-candidates/{candidate}/apply richiede sia content.apply che content.publish. La domanda viene rifiutata con JSON 409 e codice restore_candidate_stale se la pagina di origine è cambiata dopo la preparazione del candidato. Un'applicazione riuscita crea le normali versioni di sicurezza pre e post ripristino e rimuove la bozza tecnica.
  • DELETE .../version-candidates/{candidate} richiede content.apply; rimuove il candidato senza modificare la pagina di origine.

I candidati sono deliberatamente assenti dal normale rilevamento delle pagine e dall'esportazione del sito. Gli strumenti dovrebbero sempre ispezionare la versione, preparare un candidato, eseguire il rendering o aprire il suo preview_url e solo successivamente chiamare apply_url dopo l'esplicita approvazione dell'operatore.

GET /webadmin/api/pages/{page}/render richiede content.read e restituisce la pagina renderizzata esattamente come la visualizza l'anteprima dell'amministratore del browser: bozze di blocchi inclusi, X-Robots-Tag: noindex, nofollow e mai attraverso il percorso pubblico, quindi nulla al riguardo pubblica nulla.

Aggiungere ?format=html per il markup stesso invece della busta JSON e ?locale=de per eseguire il rendering di una traduzione specifica; l'impostazione predefinita è la locale predefinita del sito. Una lingua per la quale la pagina non ha traduzione restituisce 422 con page_translation_missing e le lingue che ha. Le pagine di origine Shared Slot stanno modificando l'impalcatura e restituiscono 422 con page_not_renderable, corrispondente al 404 dell'amministratore del browser su di esse.

Il rendering era già raggiungibile prima che esistesse questo endpoint: GET /webadmin/pages/{page}/preview accetta un token Bearer con content.read nonché una sessione di amministrazione, e continua a farlo. API aggiunge una busta JSON e collegamenti discovery/OpenAPI. L'anteprima del browser accetta anche un codice locale: la lingua deve essere abilitata per il sito e avere una traduzione della pagina. Omettendolo si mantiene la lingua predefinita. Entrambe le anteprime passano la lingua scelta per bloccare il rendering; né salva né pubblica contenuti.

E In ogni caso, eseguire il rendering prima di segnalare una pagina completata. L'applicazione del contenuto dice cosa è stato memorizzato, che non è la stessa cosa di ciò che viene visualizzato: un blocco wrapper senza figli, uno slot assegnato allo Shared Slot sbagliato o un layout senza gli slot presupposti dal piano, tutti si applicano in modo pulito e producono comunque una pagina che nessuno vuole.

Traduzione pagina API

Le traduzioni di pagina possiedono l'identità della pagina localizzata e le sovrascritture SEO e Open Graph a livello di pagina. L'applicazione del contenuto scrive una riga di traduzione per una lingua quando crea una pagina; questi endpoint rappresentano il modo in cui la riga viene letta e modificata successivamente.

GET /webadmin/api/pages/{page}/translations elenca ogni traduzione su una pagina con name, slug, path, seo_title, seo_description, seo_keywords, list_excerpt, og_title, og_description e og_image_media_id. list_excerpt è la frase per locale che un blocco Elenco pagine mostra sotto il titolo di questa pagina su una scheda di elenco; ha un limite massimo di 300 caratteri e, quando vuoto, ritorna alla descrizione SEO. Gli stessi campi ora appaiono su ogni traduzione in GET /webadmin/api/pages/{page}.

POST /webadmin/api/pages/{page}/translations/{locale} richiede content.apply e aggiunge una traduzione per una locale già abilitata per il sito della pagina. Il segmento {locale} accetta un codice locale o un ID numerico. È richiesto solo name: ometti slug e path ed entrambi derivano dal nome, esattamente come li deriva l'amministratore del browser. La creazione di una traduzione per una lingua già presente nella pagina restituisce 422 con il codice page_translation_exists.

PATCH /webadmin/api/pages/{page}/translations/{translation} richiede content.apply e scrive solo i campi trasportati dalla richiesta, quindi uno strumento può impostare seo_description senza inviare nuovamente l'identità della pagina. Invia null per cancellare un campo opzionale.

Slug e percorso si muovono sempre insieme. L'invio di path deriva nuovamente lo slug dal suo ultimo segmento; l'invio del solo slug sposta la pagina su /{slug}. I percorsi vengono canonizzati, confrontati con CMS riservati e percorsi host e devono rimanere univoci per il sito e le impostazioni locali. Poiché il titolo e lo slug Page leggono la traduzione predefinita, rinominando quella traduzione si rinomina la pagina stessa.

I campi esterni all'identità localizzata e al SEO vengono rifiutati con 422 e il codice unsupported_page_translation_fields, che li nomina in blocked_fields. Lo stato della pagina, il layout e il contenuto del blocco hanno i propri endpoint.

Risorse pagina API

Le pagine possono caricare i propri file /site/... CSS e JS oltre alle risorse a livello di sito:

GET    /webadmin/api/pages/{page}/assets
POST   /webadmin/api/pages/{page}/assets/{type}
PATCH  /webadmin/api/pages/{page}/assets/{pageAsset}
DELETE /webadmin/api/pages/{page}/assets/{pageAsset}

{type} è css o js. L'elenco è disponibile per qualsiasi token valido; gli endpoint di scrittura richiedono la funzionalità page-assets.write di attivazione dedicata, che non fa parte del set di creazione di pagine predefinito.

Il contratto path è deliberatamente ristretto e costituisce il limite di sicurezza per questo API:

  • deve essere un percorso locale che inizia con /site/ e termina con .css o .js corrispondente al tipo di risorsa
  • URL esterni (http://, https://), relativi al protocollo (//), javascript: e data: vengono rifiutati
  • L'attraversamento delle directory, le barre rovesciate, le stringhe di query e i frammenti vengono rifiutato

Solo questo endpoint collega un file esistente a una pagina; non scrive mai il contenuto del file. Scrivi il file stesso con le risorse del sito API (PUT /webadmin/api/sites/{site}/assets/{type}, che richiede site-assets.write) o dall'interfaccia utente di amministrazione.

I campi supportati sono path (richiesto al momento della creazione), sort_order, is_enabled e, solo per le risorse JS, is_defer, is_async e is_module. load_position deriva dal tipo (head per CSS, body_end per JS), corrispondente all'editor di amministrazione. Il tipo css/js è immutabile durante l'aggiornamento; elimina e aggiungi nuovamente per modificarlo.

A differenza degli endpoint della topologia del blocco di pagina, le risorse di pagina non sono solo bozze: possono essere modificate su qualsiasi pagina, corrispondente alla scheda Risorse di pagina di amministrazione. Ogni scrittura cattura una revisione della pagina.

Shared Slot Topologia a blocchi API Gli alberi di blocchi

Shared Slot hanno i propri endpoint di topologia perché sono condivisi su ogni pagina a cui è assegnato lo slot:

PATCH  /webadmin/api/shared-slots/{sharedSlot}/blocks/reorder
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks/{block}
DELETE /webadmin/api/shared-slots/{sharedSlot}/blocks

A l'aggiunta di blocchi rimane su POST /shared-slots/{sharedSlot}/blocks e la modifica dei campi del contenuto sicuro di un singolo blocco rimane su PATCH /blocks/{block} (che accetta già blocchi di origine Shared Slot con shared-slots.write). I nuovi endpoint aggiungono le operazioni di topologia mancanti:

  • PATCH .../blocks/reorder rinumera un gruppo di pari livello; l'array blocks deve contenere ogni ID fratello per un singolo gruppo principale esattamente una volta, nell'ordine desiderato. Richiede shared-slots.write.
  • DELETE .../blocks/{block} rimuove un blocco e il relativo sottoalbero e restituisce deleted_blocks_count.
  • DELETE .../blocks cancella ogni blocco nello slot in modo che uno strumento possa cancellare e sostituire uno Shared Slot; restituisce deleted_blocks_count.
  • Entrambe le eliminazioni richiedono shared-slots.write più la funzionalità content.blocks.delete dedicata.

A differenza delle modifiche ai blocchi di pagina, queste non sono solo bozze: Shared Slots non hanno il concetto di bozza di pagina. Il riordino o l'eliminazione di un blocco Shared Slot già pubblicato influisce quindi immediatamente su ogni pagina assegnata, motivo per cui l'eliminazione è protetta dalla capacità distruttiva content.blocks.delete. Ogni scrittura ricostruisce le assegnazioni delle pagine dello slot e acquisisce una revisione Shared Slot in modo che le modifiche rimangano reversibili.

Impostazioni sito API

Aoltre a branding, head, timezone e public-theme, sono scrivibili altri tre campi del sito. Tutti e tre richiedono site-settings.write.

PATCH /webadmin/api/sites/{site}/seo scrive seo_title, seo_description e seo_keywords: i metadati di fallback a livello di sito che una pagina pubblica eredita quando la traduzione della propria pagina non ha alcuna sostituzione. Parziale e null cancella un campo. Le sostituzioni a livello di pagina appartengono alla traduzione della pagina; vedere la traduzione della pagina API sopra.

PATCH /webadmin/api/sites/{site}/contact-recipient scrive contact_recipient_email, l'indirizzo a cui vengono inviati gli invii del modulo di contatto. Invia un valore vuoto per tornare al destinatario del sistema. Un modulo di contatto assemblato tramite API non fa nulla di utile finché non viene impostato.

PUT /webadmin/api/sites/{site}/locales sostituisce le impostazioni internazionali del sito impostate da locale_ids. La locale predefinita viene sempre mantenuta, esattamente come la mantiene il modulo di amministrazione, e le locali devono essere prima abilitate a livello globale tramite POST/PATCH /webadmin/api/locales. Non è possibile salvare una traduzione di pagina per una lingua non abilitata dal sito, quindi questo è l'endpoint che rende utilizzabile una nuova lingua su un sito.

Questo endpoint è più rigido del modulo di amministrazione sotto un aspetto: rifiuta di scollegare una locale che ha ancora traduzioni di pagina sul sito e 422 nomina la locale e il conteggio. Il modulo consente a un operatore di farlo consapevolmente; uno strumento automatico renderebbe silenziosamente orfano il contenuto.

Dominio del sito API

I record di dominio decidono quale nome host si risolve in quale sito, quindi l'amministratore del browser li mantiene dietro l'accesso a livello di sistema. Gli endpoint API sono:

  • PATCH /webadmin/api/sites/{site}/seo
  • PATCH /webadmin/api/sites/{site}/contact-recipient
  • PUT /webadmin/api/sites/{site}/locales
  • GET /webadmin/api/sites/{site}/domains richiede content.read
  • POST /webadmin/api/sites/{site}/domains richiede domains.write
  • PUT /webadmin/api/sites/{site}/domains/{domain} richiede domains.write
  • POST /webadmin/api/sites/{site}/domains/{domain}/primary richiede domains.write
  • DELETE /webadmin/api/sites/{site}/domains/{domain} richiede il distruttivo domains.delete
  • GET /webadmin/api/domains/{domain}/status richiede content.read

Questi endpoint in precedenza vivevano solo con un prefisso /admin-api e non controllavano nulla oltre alla validità del token, quindi qualsiasi token poteva aggiungere o rimuovere un dominio. Ora si trovano sotto /webadmin/api con il resto dello API e ogni percorso ha una capacità. Il prefisso /admin-api continua a funzionare per gli strumenti di provisioning esistenti, con gli stessi requisiti di capacità e un percorso aggiuntivo, GET /admin-api/sites; le nuove integrazioni dovrebbero utilizzare /webadmin/api, i cui percorsi sono coperti anche dall'esenzione CSRF che il prefisso legacy non ha mai avuto.

Shared Slot Metadati API

PATCH /webadmin/api/shared-slots/{sharedSlot} richiede shared-slots.write e modifica lo stesso Shared Slot anziché i suoi blocchi: label, handle, slot, layout e is_active. Vengono scritti solo i campi presenti. Gli handle rimangono univoci per sito, il nome dello slot deve risolversi in un tipo di slot pubblicato e la pagina di origine Shared Slot e le relative assegnazioni vengono ricostruite in seguito esattamente come le ricostruisce l'amministratore del browser. Una modifica dei metadati o dello stato acquisisce una revisione Shared Slot.

Lo spostamento di un Shared Slot in un altro sito non è supportato qui e viene rifiutato con 422 e il codice unsupported_shared_slot_fields, che copre anche qualsiasi altro campo esterno a tale set. Gli spostamenti tra siti rimangono nell'amministrazione del browser con le altre operazioni di trasferimento del sito.

DELETE /webadmin/api/shared-slots/{sharedSlot} richiede la funzionalità distruttiva shared-slots.delete e applica la stessa protezione dell'amministratore del browser: uno Shared Slot a cui fa ancora riferimento qualsiasi slot di pagina non viene mai eliminato. La risposta 422 contiene il codice shared_slot_in_use e un array usage che nomina gli slot della pagina di riferimento, quindi uno strumento può staccarli prima con PUT /webadmin/api/pages/{page}/slots/{slot}/source. Se le colonne di riferimento Shared Slot non sono state ancora migrate, l'endpoint restituisce 409 con shared_slots_not_ready invece di indovinare.

Libreria multimediale API

La libreria multimediale API è intenzionalmente divisa dalle autorizzazioni di contenuto generale in modo che agli strumenti IA/operatore possa essere concessa la scoperta dei media o la pulizia dei metadati senza ricevere poteri di scrittura non correlati.

Funzionalità:

  • media.read: elenca e controlla i record esistenti del Catalogo multimediale CMS.
  • media.upload: carica i file nel Catalogo multimediale.
  • media.write: aggiorna i metadati sicuri sui record multimediali esistenti.
  • media.replace: sostituisce un file multimediale esistente preservandone l'id multimediale.
  • media.move: sposta i media tra cartelle o cancella i suoi cartella.
  • media.delete: elimina i supporti inutilizzati con la stessa protezione dall'utilizzo del pannello di amministrazione.

Ambito fase 1:

GET /webadmin/api/media
POST /webadmin/api/media
GET /webadmin/api/media/{media}
PATCH /webadmin/api/media/{media}
POST /webadmin/api/media/{media}/replace
POST /webadmin/api/media/{media}/move
DELETE /webadmin/api/media/{media}

GET /webadmin/api/media restituisce i record multimediali esistenti con campi sicuri come ID, tipo, titolo, nome file, nome originale, tipo MIME, visibilità, URL pubblico quando disponibile, testo alternativo, dimensioni, anteprima ed etichetta metadati compatta. Richiede media.read. Durante la transizione dai token API precedenti, content.read potrebbe essere accettato anche per il rilevamento multimediale di sola lettura, in modo che le integrazioni esistenti per la creazione di pagine continuino a funzionare.

GET /webadmin/api/media/folders elenca le cartelle della libreria multimediale con i relativi conteggi multimediali e POST /webadmin/api/media/folders richiede media.write e ne crea uno da name, con slug e parent_id opzionali. Un nome che già esiste sotto lo stesso genitore viene rifiutato con 422 e il codice media_folder_exists e la risposta trasporta la cartella esistente in modo che uno strumento di ripetizione la riutilizzi invece di creare duplicati. Caricamenti di file in una cartella con folder_id; sposta i media esistenti con POST /webadmin/api/media/{media}/move.

POST /webadmin/api/media richiede media.upload e accetta caricamenti multipart/form-data nella normale libreria multimediale CMS. Il file caricato diventa una normale riga media ed è visibile nella schermata Media di amministrazione del browser e nei selettori multimediali. La convalida del caricamento rispecchia i tipi di file consentiti dalla libreria multimediale dell'amministratore del browser: immagini comuni, video, PDF, documenti Office, testo/CSV/RTF e file ZIP.

I campi dei metadati supportati sono folder_id, title, alt_text, caption e description. L'endpoint restituisce l'oggetto multimediale creato con il suo ID e l'URL pubblico quando disponibile.

PATCH /webadmin/api/media/{media} richiede media.write e aggiorna solo i metadati descrittivi sicuri:

  • title
  • alt_text
  • caption
  • description

POST /webadmin/api/media/{media}/replace richiede media.replace e sostituisce il file binario archiviato preservando l'ID del supporto e i riferimenti esistenti. Il file sostitutivo deve essere risolto nello stesso tipo di supporto del record esistente, ad esempio da immagine a immagine o da documento a documento. La risposta include i dettagli sull'utilizzo corrente in modo che gli strumenti possano vedere se la sostituzione influisce sui blocchi, sul branding del sito o sul SEO della pagina.

POST /webadmin/api/media/{media}/move richiede media.move e accetta folder_id, incluso null per cancellare l'assegnazione della cartella.

DELETE /webadmin/api/media/{media} richiede media.delete e utilizza la stessa protezione dall'utilizzo dell'amministratore del browser. I media a cui fanno riferimento blocchi, gallerie, allegati, branding del sito o SEO della pagina non vengono eliminati; API restituisce invece 422 con i dettagli di utilizzo.

Questo API non supporta esplicitamente:

  • modifica diretta di disco, percorso, nome file, tipo MIME, tipo, visibilità, dimensione, dimensioni, uploader o relazioni di utilizzo
  • recupero o importazione di URL multimediali remoti

Questo limite consente agli strumenti IA/operatore di ricevere solo i poteri multimediali di cui hanno bisogno. Ad esempio, un token di creazione di pagine può leggere e caricare contenuti multimediali senza poter eliminare o sostituire i file esistenti, mentre a un token di manutenzione attendibile può essere concesso esplicitamente media.replace o media.delete.

Sostituzione di slot su pagine in bozza esistenti

La sostituzione su pagine in bozza esistenti resta all'interno del contratto validate/apply:

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

Utilizzare mode: replace_existing_draft_page per sostituire uno o più spazi di proprietà della pagina su una bozza di pagina esistente. L'operazione richiede content.validate per la convalida e content.apply per l'applicazione. Non richiede pages.delete, perché non è un'operazione generale di eliminazione delle pagine.

Traduzione della pagina path è l'URL pubblico canonico. I nuovi piani dovrebbero utilizzare percorsi come /contact, /features, /games/fruit-train o /docs/internal-content-api; /p/... è solo compatibilità legacy. I percorsi con barra sono normalizzati segmento per segmento, quindi /docs/internal-content-api/ diventa /docs/internal-content-api e non viene compresso in docsinternal-content-api. CMS deriva lo slug della pagina breve dal segmento del percorso finale, quindi /games/fruit-train memorizza lo slug fruit-train e il percorso /games/fruit-train. Le aree di instradamento riservate come /webadmin, /webadmin/api, /cms, /search, /search.json, /contact-messages, /install e gli instradamenti di autenticazione host non possono essere creati come percorsi di pagine pubbliche.

Esempio:

{
  "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."
          }
        }
      ]
    }
  }
}

Regole:

  • la pagina di destinazione deve essere in stato draft
  • è richiesto expected_path oppure expected_updated_at
  • expected_path usa il percorso pubblico canonico della Page Translation, non un alias legacy /p/...
  • la pagina di destinazione deve appartenere al sito richiesto e la lingua (locale) deve essere abilitata per quel sito
  • ogni slot deve esistere sulla pagina e usare blocchi di proprietà della pagina
  • gli slot basati su Shared Slot vengono rifiutati anziché svuotati
  • vengono rimossi solo i blocchi presenti nei replace_slots indicati
  • i vecchi blocchi vengono rimossi e i nuovi scritti in un'unica transazione
  • le revisioni di pagina vengono acquisite prima e dopo l'applicazione
  • non avvengono pubblicazione, recupero/importazione di media, eliminazioni estese o rimozione delle assegnazioni di Shared Slot

Aggiornamenti graduali della pagina pubblicata

Le pagine pubblicate non possono essere sostituite direttamente. Per le pagine di documenti con collegamento all'origine o altre pagine attive che devono rimanere pubbliche mentre vengono preparate le modifiche ai contenuti, utilizzare le modalità di aggiornamento graduale:

create_staged_update_for_published_page
replace_staged_page_update
promote_staged_page_update

create_staged_update_for_published_page crea una bozza di pagina di gestione temporanea dalla pagina di origine pubblicata solo quando tale pagina di origine non dispone già di una bozza di aggiornamento graduale attiva. La ripetizione della chiamata di creazione per la stessa pagina di origine restituisce la bozza in fasi attiva esistente con data.reused_staged_update=true invece di creare un'altra pagina tecnica. La pagina di origine rimane pubblicata nel percorso pubblico esistente. La pagina organizzata archivia i metadati settings.staged_update con l'ID della pagina di origine, il percorso di origine, il timestamp aggiornato dell'origine, lo stato del ciclo di vita e gli slot gestiti. Utilizza un percorso bozza interno come /staged-updates/page-123/update-456, quindi non entra in conflitto con il percorso canonico di origine e non viene instradato pubblicamente. Il normale URL di anteprima dell'amministratore /webadmin/pages/{page}/preview può eseguire il rendering della pagina organizzata per sessioni di amministrazione autenticate o token di connessione CMS API con content.read.

replace_staged_page_update riutilizza le regole di sostituzione della bozza rispetto alla pagina bozza graduale. Usalo per ogni revisione successiva dopo l'esistenza di una bozza graduale. Sostituisce solo gli slot di proprietà della pagina e rifiuta gli slot supportati da Shared Slot.

promote_staged_page_update applica nuovamente il contenuto dello slot di proprietà della pagina in scena alla pagina di origine pubblicata in una transazione. Conserva il percorso della pagina di origine, lo stato, il layout, le assegnazioni Shared Slot e le impostazioni della pagina a meno che non venga fornito un aggiornamento source_sync incluso nella lista consentita. I blocchi di proprietà della pagina promossa vengono scritti come published in modo che la pagina pubblica rifletta immediatamente il contenuto promosso. Il contenuto Shared Slot non viene mai messo in cascata. Una volta acquisite le versioni di sicurezza pre/post-promozione della pagina di origine, la pagina tecnica preparata viene eliminata nella stessa transazione; una promozione fallita lascia quindi la bozza disponibile per la correzione. La promozione richiede la funzionalità di percorso normale content.apply e la funzionalità avanzata content.publish.

Al'abbandono di una bozza provvisoria attiva utilizza DELETE /webadmin/api/pages/{staged_page}/staged-update. Questo endpoint di eliminazione ristretta richiede content.apply, accetta solo una bozza di pagina con metadati di aggiornamento graduale attivi e non modifica mai la pagina di origine pubblicata o le relative versioni salvate. Evita di concedere a uno strumento di creazione di pagine l'ampia capacità pages.delete semplicemente per ripulire la propria bozza tecnica.

Se un piano di applicazione normalizzato supera la convalida ma fallisce durante le scritture transazionali, API restituisce la convalida normale JSON con ok=false e un errore in plan.apply. L'eccezione dettagliata viene registrata nei registri dell'applicazione; Le risposte API rimangono pubbliche e non includono analisi dello stack, elementi interni del database, token o percorsi locali.

Esempio di flusso di lavoro a fasi:

{
  "plan": {
    "mode": "create_staged_update_for_published_page",
    "site": "default",
    "locale": "en",
    "page": {
      "id": 123
    },
    "expected_source_path": "/docs",
    "managed_slots": ["main"]
  }
}

Quindi sostituisci il contenuto messo in scena:

{
  "plan": {
    "mode": "replace_staged_page_update",
    "staged_page_id": 456,
    "expected_source_page_id": 123,
    "expected_source_path": "/docs",
    "replace_slots": {
      "main": [
        {
          "type": "plain_text",
          "translations": {
            "content": "Replacement staged content."
          }
        }
      ]
    }
  }
}

Promuovi dopo l'anteprima e l'approvazione esplicita:

{
  "plan": {
    "mode": "promote_staged_page_update",
    "staged_page_id": 456,
    "expected_source_page_id": 123,
    "expected_source_path": "/docs",
    "promote_slots": ["main"]
  }
}

Non è richiesta alcuna nuova tabella dello schema per questo flusso di lavoro; i metadati del ciclo di vita a fasi attive utilizzano la colonna Pagina settings JSON esistente. Le pagine tecniche promosse non vengono conservate perché le versioni della pagina di origine forniscono il percorso di ripristino.

Le installazioni aggiornate da una versione che archiviava le pagine organizzate promosse possono visualizzare in anteprima e rimuovere i record legacy una volta:

php artisan webblocks:staged-updates:prune --dry-run
php artisan webblocks:staged-updates:prune

Il comando seleziona solo le pagine archiviate i cui metadati gestiti indicano esplicitamente type=published_page_update e state=promoted. Le bozze attive e le pagine archiviate ordinarie non sono mai candidate.

Metadati di sincronizzazione della sorgente

I piani di contenuto possono conservare un oggetto source_sync limitato e privo di segreti per i flussi di sincronizzazione della documentazione IA/operatore. Le impostazioni di pagina arbitrarie vengono rifiutate. La forma accettata è:

{
  "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 salva questi metadati nelle impostazioni della pagina e le risposte API di elenco/dettaglio delle pagine espongono gli stessi campi di source_sync ammessi, per confronti futuri. Non includete token, valori d'ambiente, percorsi assoluti locali o del server, né altri segreti.

Endpoint di pubblicazione espliciti

La pubblicazione è separata da content apply e richiede un token con content.publish.

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

POST /webadmin/api/pages/{page}/publish pubblica il record della pagina. Il suo payload predefinito riguarda solo la pagina:

{
  "include_page_owned_blocks": false
}

Regole:

  • omesso include_page_owned_blocks si comporta come false
  • include_page_owned_blocks: false pubblica solo il record della pagina e lascia invariati i blocchi bozza o in revisione
  • include_page_owned_blocks: true pubblica blocchi bozza e in revisione di proprietà degli slot di pagina non condivisi della pagina, inclusi i blocchi secondari nidificati
  • I blocchi già pubblicati rimangono invariati
  • Shared Slot gli slot supportati sono esclusi e riportato nella risposta
  • campi a cascata Shared Slot non supportati come publish_shared_slots, include_shared_slot_blocks o shared_slot_cascade restituiscono JSON 422
  • la risposta include ID pagina/stato/metadati del percorso, se sono stati inclusi blocchi di proprietà della pagina, il conteggio pubblicato, riepiloghi Shared Slot esclusi e ID revisione della pagina

POST /webadmin/api/pages/{page}/publish-page-owned-blocks pubblica solo blocchi di proprietà della pagina non pubblicati e non modifica lo stato del flusso di lavoro della pagina. Utilizza la stessa funzionalità content.publish e la stessa regola di esclusione Shared Slot.

POST /webadmin/api/pages/{page}/archive toglie la pagina dal sito pubblico: le pagine archiviate restituiscono 404 ai visitatori e le voci di menu collegate alla pagina interrompono il rendering nei menu pubblici. Utilizza la stessa funzionalità content.publish e rispecchia le regole del flusso di lavoro dell'amministratore: consentito da in_review e published, una pagina bozza restituisce JSON 422, la riarchiviazione di una pagina archiviata non è riuscita e le pagine di aggiornamento graduale vengono rifiutate (promuoverle o eliminarle invece). La risposta include i metadati della pagina, from_status e l'ID di revisione della pagina acquisita. Pubblicando nuovamente la pagina si inverte l'archivio.

I/gli strumenti dell'operatore non devono presupporre che la pubblicazione della pagina renda pubblici tutti i contenuti del blocco. Utilizza include_page_owned_blocks: true solo quando l'utente ha approvato esplicitamente la pubblicazione di tutti i blocchi di proprietà della pagina non pubblicati per quella pagina. Il contenuto Shared Slot deve essere rivisto e pubblicato separatamente.

Endpoint del contratto di contenuto

GET /webadmin/api/content-contract è un endpoint di rilevamento di sola lettura per strumenti IA/operatore attendibili. Restituisce il prefisso API, URL di convalida/applicazione, modello URL di anteprima dell'amministratore, flag di sicurezza, URL di rilevamento, modelli di creazione di pagine consigliati, un contratto di direzione di progettazione leggibile dalla macchina e metadati del contratto di blocco ripuliti.

Prima di scegliere un albero di blocchi, gli strumenti devono leggere design_direction, selezionare un valore per ciascuno di character, density, typography, geometry, imagery, corners, contrast e framing e spiega come la mappa di composizione implementa tali scelte. Si tratta di un contratto di pianificazione piuttosto che di un archivio di contenuti nascosti: il risultato è espresso attraverso impostazioni di blocco native, token di temi pubblici e sito stabile CSS. La sua politica di composizione rende le colonne semplici per impostazione predefinita per i nuovi piani API, mantiene l'attivazione delle carte e richiede una giustificazione del limite del contenuto/azione per ogni raccolta di carte. Una fonte contenente tre brevi articoli non è una tale giustificazione.

framing è una dimensione di pianificazione, non dati di pagina persistenti. Scegli open, restrained, framed o dense-ui in base al contenuto e al contesto. Non utilizzare una scheda o un pannello bordato semplicemente per organizzare una sezione. L'inquadratura deve comunicare l'indipendenza semantica, l'interazione o i confini dell'entità. I contenitori esterni degli eroi, i gruppi di funzionalità/principi, gli involucri di sezione, le colonne di navigazione/piè di pagina, le bande di invito all'azione, le statistiche decorative e le suddivisioni editoriali non sono incorniciate per impostazione predefinita. Preferisci spazi bianchi, gerarchia tipografica, layout asimmetrico, divisori, cambi di tono, sezioni ampie, allineamento, offset/sovrapposizione e regole limitate. La verifica richiesta della superficie intelaiata deve giustificare ogni superficie intelaiata non di entità; “separare visivamente la sezione” non è sufficiente.

La sezione adiacente design_fixtures pubblica alberi di blocchi nativi canonici, indicazioni di progettazione compatibili, hook pubblici previsti, anti-pattern e dimensioni di acquisizione deterministiche per desktop/mobile. Il suo stato distingue un contratto di rendering supportato dall'origine dagli screenshot approvati dall'uomo. Gli strumenti possono utilizzare un albero di riferimento come riferimento alla composizione, ma non devono richiedere l'approvazione visiva mentre il registro riporta render_contract_ready_capture_pending. Consulta i contratti di composizione disponibili in design_fixtures nella risposta di discovery.

L'endpoint è un comportamento del prodotto CMS generico. Non deve restituire segreti specifici dell'installazione, valori di token, contenuti grezzi del Blade, percorsi assoluti del filesystem, percorsi di server privati ​​o istruzioni specifiche del sito. Le righe del contratto di blocco possono includere handle/slug, etichetta, categoria, stato, contenitore e supporto figlio, campi traducibili, campi di impostazioni condivise e comportamento root del renderer pubblico.

Gli strumenti

I devono chiamare questo endpoint o GET /webadmin/api/block-types prima di creare un piano e devono utilizzare solo gli handle presenti nell'installazione corrente.

I contratti

Block possono esporre campi di icone e badge pubblici facoltativi, inclusi settings.icon_slug, settings.icon_tone, settings.icon_size, settings.badge_tone e la copia tradotta eyebrow/badge_label. Gli strumenti devono trattare le lumache delle icone come selezioni supportate dal catalogo anziché come testo libero; il rendering pubblico ignora le icone sconosciute o inattive e genera solo classi wb-icon wb-icon-{slug} sicure per le righe del catalogo WebBlocks UI attive. settings.icon_tone è un'impostazione del tono visivo pubblico condiviso, non una copia di proprietà locale, e accetta solo default, soft, brand, accent, highlight, bold e quiet; settings.icon_size accetta default, sm, lg o xl e si associa alla classe di dimensioni WebBlocks UI corrispondente. info, success, warning e danger rimangono toni di stato semantici per badge, avvisi, convalida e feedback. I toni o le dimensioni delle icone sconosciute vengono rifiutati durante la convalida del piano di contenuti o ignorati dal rendering pubblico come fallback sicuro. Il tono del badge viene visualizzato solo quando il blocco possiede anche la copia tradotta dell'etichetta del badge.

GET /webadmin/api/icon-catalog?context=content restituisce gli slug di icone di sicurezza attivi che i client API possono assegnare ai blocchi di contenuto pubblico. Utilizzare context=navigation per classificare per primi i suggerimenti contrassegnati dai tag di navigazione per le scelte delle icone degli elementi di navigazione; entrambi i contesti restituiscono comunque ogni icona attiva perché il contesto è un suggerimento piuttosto che una lista consentita. Gli strumenti API devono leggere questo endpoint prima di inviare i valori settings.icon_slug o di navigazione icon e non devono indovinare i nomi delle icone dal manifest WebBlocks UI.

Il contratto contact_form include metadati aggiuntivi del modulo sicuro: schema delle impostazioni, campi tradotti, endpoint di invio pubblico POST /contact-messages, comportamento del browser CSRF richiesto, regole di convalida del server, campo di controllo antispam generato nascosto di proprietà del CMS, comportamento di successo del campo di controllo generico, note di classificazione/quarantena dello spam, comportamento di archiviazione prima della notifica, ordine di fallback del destinatario, errore di notifica sicura registrazione e comportamento di revisione /webadmin/contact-messages. Il campo di controllo viene generato dal renderer, non fa parte del normale input del visitatore e non deve essere creato manualmente da API o da strumenti AI/operatore. Gli strumenti della pagina di contatto dovrebbero utilizzare quel blocco nativo anziché HTML attendibile, markup del modulo non elaborato o moduli mailto:. Il vecchio campo website non è più il contratto pubblico del modulo di contatto.

La guida alla creazione di pagine AI leggibile dall'uomo viene fornita con installazioni native del pacchetto su vendor/fklavyenet/webblocks-cms/docs/ai-page-building-guide.md.

Superficie API

Endpoint di discovery

  • 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/locale-options
  • POST /webadmin/api/locales
  • PATCH /webadmin/api/locales/{locale}
  • GET /webadmin/api/page-layouts
  • GET /webadmin/api/block-types
  • GET /webadmin/api/icon-catalog
  • GET /webadmin/api/content-contract

Endpoint delle pagine

  • GET /webadmin/api/pages
  • GET /webadmin/api/pages/{page}
  • GET /webadmin/api/pages/{page}/render
  • GET /webadmin/api/pages/{page}/translations
  • POST /webadmin/api/pages/{page}/translations/{locale}
  • PATCH /webadmin/api/pages/{page}/translations/{translation}
  • POST /webadmin/api/pages/{page}/sync-layout-slots
  • PATCH /webadmin/api/pages/{page}/layout
  • POST /webadmin/api/pages/{page}/slots/{slot}/shared-slot
  • PUT /webadmin/api/pages/{page}/slots/{slot}/source

Endpoint dei blocchi

  • 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
  • PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/{item}
  • PATCH /webadmin/api/navigation-menus/{navigationMenu}/items/reorder
  • DELETE /webadmin/api/navigation-menus/{navigationMenu}/items/{item}

I menu di navigazione utilizzano il modello CMS navigation_items.menu_key esistente. La fase 2A supporta gli handle di menu CMS forniti come primary, footer, mobile, legal e docs; non aggiunge una tabella di menu separata. La creazione di un menu di navigazione viene considerata come la creazione di un gruppo di menu sicuro con ambito sito con elementi iniziali facoltativi. Si rifiuta di sovrascrivere un sito/menu che contiene già items.

La creazione, l'aggiornamento, le modifiche alla visibilità e il riordino degli elementi di navigazione richiedono navigation.write. L'eliminazione richiede la funzionalità distruttiva esplicita navigation.delete. Gli aggiornamenti degli articoli supportano label/title, url, link_type, page_id, target, visibility, sort_order/position, parent_id e icon dove tali campi sono validi per il tipo di collegamento selezionato. Gli aggiornamenti sono parziali: i campi assenti dal payload mantengono i valori memorizzati senza riconvalida, quindi le righe legacy (un ordinamento pre-albero-editor pari a 0, un figlio nidificato sotto un genitore di tipo pagina) rimangono aggiornabili; le regole si applicano ai valori effettivamente inviati da una richiesta.

Item accettano anche una chiave locale opzionale (un codice locale abilitato per il sito dell'elemento), rispecchiando le scritture di traduzione dei blocchi. Senza locale o con la locale predefinita del sito, label/title scrive il titolo canonico della locale predefinita. Con un locale non predefinito, il valore label/title viene archiviato come riga di traduzione con chiave locale per quell'elemento e il titolo canonico rimane intatto; altri campi della stessa richiesta (visibilità, posizione e così via) rimangono condivisi e si applicano all'elemento stesso. Il rendering pubblico seleziona il titolo di navigazione per la locale richiesta e torna al titolo canonico della locale predefinita quando non esiste alcuna riga di traduzione. I payload di lettura degli elementi espongono i titoli memorizzati per locale come una mappa title_translations codificata dal codice locale. I payload di riordino devono includere ogni elemento nel sito/menu selezionato esattamente una volta. L'eliminazione rifiuta gli elementi principali che hanno ancora elementi secondari, quindi gli strumenti devono prima spostare o eliminare i secondari invece di fare affidamento sulle cascate.

Gli URL degli elementi di navigazione possono essere percorsi interni come /, /about, /contact e /#platform oppure URL http/https sicuri. Utilizza un percorso più un frammento per gli ancoraggi della stessa pagina; i valori di soli frammenti non elaborati come #platform non sono URL di navigazione. API rifiuta javascript:, data:, URL relativi al protocollo, attraversamento, URL non formati correttamente, target non supportati ed etichette vuote. Gli endpoint di navigazione non creano pagine, pubblicano pagine, eseguono la scansione di siti, recuperano URL remoti o eliminano a catena elementi secondari.

La creazione di

Endpoint degli Shared Slot

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

Shared Slot ha come ambito il sito e rifiuta handle duplicati per lo stesso sito. I blocchi Shared Slot riutilizzano lo stesso scrittore del payload del blocco utilizzato dai blocchi di proprietà della pagina, quindi la copia di proprietà locale rimane nelle righe di traduzione e le impostazioni condivise rimangono nel percorso dei record/impostazioni del blocco. Le richieste di aggiunta blocco Shared Slot possono includere parent_id o parent_block_id per aggiungere un blocco sotto un blocco esistente nello stesso albero di origine Shared Slot quando quel genitore accetta il tipo figlio richiesto. I blocchi Shared Slot vengono creati come contenuto bozza e richiedono POST /webadmin/api/shared-slots/{sharedSlot}/publish-blocks esplicito con shared-slots.write più content.publish prima di essere visualizzati pubblicamente. L'importazione e l'assegnazione dei media rimangono al di fuori di questa fase.

Assegnazione degli slot di pagina

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

L'endpoint shared-slot assegna uno Shared Slot attivo compatibile esistente sullo stesso sito a uno slot di pagina esistente. Non pubblica la pagina. Rifiuta Shared Slots cross-site, inattivo e incompatibile. Si rifiuta inoltre di cambiare uno slot che contiene ancora blocchi di proprietà della pagina, perché la Fase 2A non elimina o sostituisce automaticamente tali blocchi.

PUT .../source scrive l'origine del contenuto dello slot ed è la via d'uscita: source_type accetta page, shared_slot o disabled. Richiede content.apply e shared_slot richiede inoltre shared-slots.write e le stesse regole di compatibilità dell'endpoint assegnato, a cui delega. Lo scollegamento cancella shared_slot_id e lascia intatti i blocchi di proprietà della pagina, quindi page li esegue nuovamente il rendering e disabled mantiene il wrapper dello slot senza nulla all'interno. Prima che questo endpoint esistesse, API poteva creare un riferimento Shared Slot che non aveva modo di rimuovere: l'unica uscita era la schermata di amministrazione autenticata dalla sessione.

Se il layout di pagina contiene uno slot come header ma il record della pagina è stato creato prima che esistesse quello slot di pagina, chiamare prima POST /webadmin/api/pages/{page}/sync-layout-slots. La sincronizzazione degli slot è idempotente e crea solo gli slot di pagina mancanti dal layout di pagina selezionato; non elimina mai slot, blocchi, stati disabilitati, assegnazioni Shared Slot, traduzioni o revisioni esistenti. Per una nuova intestazione Shared Slot, pubblicare esplicitamente i blocchi Shared Slot prima di aspettarsi l'output pubblico.

Assegnazione layout di pagina

PATCH /webadmin/api/pages/{page}/layout

Scrive il layout di pagina di una pagina esistente (public_shell). Il modulo di modifica dell'amministratore potrebbe sempre cambiare questo; API in precedenza poteva impostarlo solo durante la creazione di una pagina. content.apply lo copre. layout (o handle) deve essere uno degli handle attivi di GET /webadmin/api/page-layouts: l'alias legacy dashboard viene ancora normalizzato in docs. Corrisponde al contratto di PageController::update(): non modifica gli slot di pagina in caso di semplice modifica del layout, quindi neanche questo endpoint lo fa. Chiama sync-layout-slots separatamente se il nuovo layout definisce gli spazi che la pagina non ha ancora.

Endpoint presentazione sito

POST /webadmin/api/sites/{site}/public-theme
PATCH /webadmin/api/sites/{site}/branding
PATCH /webadmin/api/sites/{site}/timezone
GET /webadmin/api/sites/{site}/assets/{css|js}
PUT /webadmin/api/sites/{site}/assets/{css|js}

Questo endpoint aggiorna solo la preimpostazione del tema pubblico del sito sicuro utilizzata dal rendering pubblico. Invia public_theme_preset o theme con uno dei valori Site::PUBLIC_THEME_PRESETS supportati come canvas, atlas, pulse, prism, graphite o horizon. Utilizzalo quando il rilevamento API mostra il rendering di un sito con la preimpostazione data-wb-public-theme errata; non tentare di sovrascrivere la preimpostazione con blocchi di contenuto.

PATCH /webadmin/api/sites/{site}/branding richiede site-settings.write e aggiorna i campi di branding del sito pubblico sicuro che sono visibili anche in Sites -> Edit Site -> Branding:

  • display_name
  • tagline
  • favicon_media_id
  • social_image_media_id
  • La sostituzione di Media conserva l'ID multimediale e i riferimenti editoriali, cancella le trasformazioni di immagini obsolete e deriva varianti future dal binario di sostituzione.

I campi favicon e immagine social devono fare riferimento ai record di immagini dalla libreria multimediale CMS e null cancella il supporto selezionato. Le modifiche alla favicon del sito pubblico dovrebbero utilizzare questo endpoint in modo che il risultato rimanga modificabile dall'amministratore. Non sovrascrivere /cms/brand/*; tali file sono risorse del prodotto/shell di amministrazione CMS, non branding pubblico a livello di sito.

PATCH /webadmin/api/sites/{site}/timezone richiede site-settings.write e imposta il fuso orario di un sito: un identificatore IANA standard come Europe/Berlin. Tutto ciò che risolve l'ora locale per quel sito, come le finestre di disponibilità delle prenotazioni di un plug-in, viene interpretato rispetto a questo valore. Invia un timezone vuoto per ripristinarlo nel fuso orario del sistema a livello di installazione da Admin -> System Settings.

GET /webadmin/api/sites/{site}/assets/{css|js} richiede site-assets.read e legge il file di override canonico a livello di sito fisico. Restituisce relative_path, public_path, exists, contents, checksum, size, updated_at, readiness, guidance e CSS analysis senza esporre il percorso assoluto del server. L'oggetto readiness segnala se la directory del sito, la directory delle risorse e il file sono sufficientemente scrivibili da consentire a CMS di creare o aggiornare la risorsa. L'oggetto guidance indica agli strumenti AI/operatore di mantenere CSS token-first, mode-aware e native-block-first. Per CSS, asset.analysis.mode_awareness riporta status, messaggi di avviso, chiavi anti-pattern rilevate, segnali come il conteggio dei colori letterali e token --wb-public-* consigliati. PUT /webadmin/api/sites/{site}/assets/{css|js} richiede site-assets.write e accetta:

  • contents
  • expected_checksum

L'endpoint di scrittura utilizza lo stesso archivio di file fisici di Sites -> Edit Site -> Assets. Scrive solo public/site/{site_handle}/css/site.css o public/site/{site_handle}/js/site.js, crea directory mancanti al primo salvataggio, rifiuta i valori expected_checksum obsoleti e memorizza un'istantanea di revisione pre-sovrascrittura prima di sostituire un file modificato esistente. Non esiste alcun percorso di fallback del database e nessun scrittore di percorsi /site/... arbitrario. Se le autorizzazioni di hosting impediscono la creazione di directory o la scrittura di file, l'endpoint restituisce JSON 422 con errors.0.path = asset.write e i metadati di disponibilità correnti invece di un errore del server HTML.

Per le scritture CSS, utilizzare la struttura/impostazioni dei blocchi nativi, i campi di sfondo della libreria multimediale, i token del tema pubblico e gli stili dei componenti WebBlocks UI ereditati prima di aggiungere selettori personalizzati. Se i colori personalizzati sono inevitabili, definisci proprietà semantiche personalizzate con valori chiari e scuri legati ai selettori della modalità attiva o ai token del tema pubblico in modo che le pagine pubbliche rimangano coerenti in modalità Chiaro/Scuro/Auto. Evita sfondi chiari codificati a livello di pagina, testo scuro, carte bianche o tavolozze una tantum in modalità scura quando i token del tema pubblico possono esprimere il design. PUT non rifiuta gli avvisi di riconoscimento della modalità perché alcuni sistemi di marca necessitano di colori personalizzati intenzionali, ma gli strumenti dovrebbero considerare asset.analysis.mode_awareness.status = warning come lavoro da rivedere, segnalare o correggere prima di considerare completata una migrazione o una nuova configurazione del sito.

I commenti vengono rimossi prima dell'analisi: un foglio di stile che documenta se stesso citando la regola che ripara non segnala il colore citato come uno dei suoi e un ambito in modalità oscura nominato solo in un commento non conta come presente.

I controlli anti_patterns riguardano il paint-wide, quindi ognuno richiede che il suo token sia l'ultimo composto del selettore e finisca dove finisce il nome: body { background: #fff } viene riportato, body .promo { background: #fff } e .wb-public-body { ... } non lo sono, e .wb-card-title non lo è leggere come .wb-card. Una regola che dipinge un elemento viene lasciata ai segnali di colore letterale anziché riportata come anti-pattern a livello di pagina.

asset.analysis.mode_awareness è intenzionalmente un contratto euristico, non un linter CSS. Segnala pass o warning, warnings, anti_patterns rilevato, signals semplice come dichiarazioni di colore letterali, uses_public_theme_tokens e has_dark_mode_scope, oltre ai ruoli token --wb-public-* consigliati. Gli strumenti dovrebbero utilizzare questo segnale per individuare tempestivamente le probabili regressioni in modalità mista e fare comunque affidamento sul QA visivo per la parità del progetto finale.

Embedded Application Risorse API

Il codice dell'applicazione non deve essere unito al codice site.css o site.js globale di un sito. Uno Embedded Application registrato può possedere CSS fisico, JavaScript e una voce index.html gestita nella directory pubblica con ambito sito:

GET    /webadmin/api/sites/{site}/applications/{application}/assets
GET    /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
PUT    /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
DELETE /webadmin/api/sites/{site}/applications/{application}/assets/{css|js|html}/{filename}
POST   /webadmin/api/sites/{site}/applications/{application}/package

CSS e JavaScript utilizzano il percorso pubblico deterministico /site/{site_handle}/applications/{application_handle}/{type}/{filename}. Il tipo HTML accetta solo index.html, lo archivia nella radice dell'applicazione e restituisce il percorso pubblico stabile /webblocks-applications/{application_handle}/index.html selezionato dall'host. La scrittura di questa voce gestita passa la definizione alla modalità iframe e attiva l'URL. GET, PUT e DELETE richiedono rispettivamente applications.read, applications.write e applications.delete. I nomi dei file sono solo nomi di base e devono terminare con l'estensione .css, .js o .html selezionata. HTML non accetta nomi di file diversi da index.html; attraversamento, percorsi nidificati, altri tipi di file e URL remoti vengono rifiutati.

PUT accetta contents e expected_checksum. Invia null solo quando si crea un file mancante; leggere prima un file esistente e inviarne il checksum quando lo si sostituisce. Le sostituzioni e le cancellazioni conservano le copie di revisione. L'eliminazione viene rifiutata mentre la definizione Embedded Application fa ancora riferimento al percorso pubblico della risorsa. Dopo aver scritto una risorsa, utilizza la public_path restituita in css_assets o js_assets; il Blocco Applicazione lo carica quindi solo dove è posizionata l'applicazione.

Le applicazioni complete dovrebbero utilizzare l'endpoint del pacchetto invece di scrivere i file uno per uno. Richiede applications.write e multipart/form-data con un campo ZIP package (dimensione massima di caricamento 50 MB). Per prima cosa incrementare version dell'applicazione registrata con PATCH /webadmin/api/applications/{application}; quindi carica un ZIP contenente index.html nella radice e utilizza gli URL delle risorse relative al suo interno. Una risposta riuscita restituisce la versione del pacchetto, l'immutabile entry_url attivato, il conteggio dei file e la dimensione dei byte espansi, oltre alla definizione dell'applicazione aggiornata. Le versioni installate non possono essere sovrascritte. Gli errori di sicurezza di convalida e archiviazione restituiscono errori strutturati JSON 422 in errors[0].path = application_package (o application_package.package per il campo multiparte).

Endpoint Content Validate / Apply

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

I piani di contenuto possono assegnare record CMS Media Library già caricati a blocchi supportati da supporti nativi. Utilizzare media_id o asset_id sui blocchi image, navbar-brand, sidebar-brand, file, download e video con supporti del tipo corrispondente. Utilizzare media_id o asset_id su hero, section, card, cta e content_header quando il supporto è l'immagine di sfondo del blocco, con settings.background_position e settings.background_overlay. Utilizzare gallery_items o gallery_media_ids su blocchi gallery con record di supporti immagine; API conserva l'ordine degli elementi della Galleria inviato durante la scrittura di block_media.position. Per le immagini del contenuto della scheda, crea la normale struttura nidificata, ad esempio card -> card_body -> image e inserisci media_id nel blocco figlio image. I piani di contenuto rifiutano ancora remote_url e source_url; caricare prima i file tramite POST /webadmin/api/media o importare prima un URL di file pubblico approvato tramite POST /webadmin/api/media/fetch, quindi assegnare media.id.

restituito

Sicurezza Del Piano Di Contenuto

I piani usano modalità esplicite di bozza o aggiornamento preparato. Validare prima dell’applicazione e mantenere la pubblicazione come operazione autorizzata separatamente. Le pagine pubbliche richiedono un aggiornamento preparato proprio, non la sostituzione diretta.

Un piano può riferirsi a record approvati della libreria. Recuperi remoti, caricamenti e altre operazioni usano endpoint e capacità dedicati; il piano non concede tali permessi. Scoprire gli endpoint correnti prima di modificare.

Le scritture JSON Bearer-token usano l’autorizzazione del token. La discovery minima senza autenticazione non concede accesso al contenuto. Vedere Authentication e Capabilities per l’ambito richiesto.

Forma degli errori JSON

Gli errori dell'API sono esclusivamente JSON. Non devono reindirizzare al login, mostrare pagine CSRF o esporre stack trace. Campi comuni:

{
  "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": []
}

Estati previsti:

  • 401 invalid_internal_api_token per token mancanti, non validi, revocati, scaduti o non più supportati dall'utente
  • 403 missing_internal_api_capability per funzionalità mancanti
  • 403 delegated_site_access_denied quando un token personale ha come target un sito al di fuori del suo ambito attivo
  • 403 delegated_workflow_access_denied quando il proprietario non può modificare la pagina nel suo stato del flusso di lavoro corrente
  • 403 delegated_operation_denied per operazioni a livello di installazione che rifiutano i dati personali tokens
  • 403 delegated_network_access_denied quando l'IP risolto è esterno alla lista consentita dei token personali
  • 429 personal_api_token_rate_limit_exceeded quando viene raggiunto il tetto personale; i clienti devono rispettare Retry-After
  • 422 per errori di convalida

Esempi di Resource API

Rendering dell'istantanea di amministrazione degli aggiornamenti di sistema

GET /webadmin/api/admin-render/system-updates
GET /webadmin/api/admin-render/system-updates?format=html

Richiede admin.render e un token creato da un utente che può accedere a System. La risposta JSON include l'amministratore renderizzato HTML per la schermata System Updates consentita; ?format=html restituisce direttamente text/html in modo che gli strumenti dell'operatore possano caricare l'istantanea in un browser locale e acquisire schermate per il confronto visivo. L'endpoint è di sola lettura e non deve fare clic, installare, pubblicare o modificare lo stato di aggiornamento.

Elencare le pagine

GET /webadmin/api/pages

Leggere i dettagli di una pagina

GET /webadmin/api/pages/{page}

Lettura dei commenti sull'impegno

GET /webadmin/api/engagement/comments?status=pending&per_page=25

Richiede engagement.read. I filtri supportati sono status, site_id, page_id, block_id, search e per_page. Le risposte includono il corpo del commento, lo stato, il punteggio/motivi dello spam, i riferimenti alla pagina/blocco di origine e i timestamp, ma non espongono hash dei visitatori, hash IP o valori dello user-agent.

Commento sull'impegno moderato

PATCH /webadmin/api/engagement/comments/{comment}
Content-Type: application/json

{"status":"approved"}

Richiede engagement.moderate. Gli stati supportati sono pending, approved, rejected, spam e hidden.

Leggi le valutazioni del coinvolgimento

GET /webadmin/api/engagement/ratings?block_id=123

Richiede engagement.read. I filtri supportati sono status, site_id, page_id, block_id e per_page. Le risposte includono righe di valutazione più riepiloghi di totale, media e conteggio dei valori, ma non espongono gli hash dei visitatori, gli hash IP o i valori dello user-agent.

I campi

Elencare i blocchi

GET /webadmin/api/blocks

Leggere i dettagli di un blocco

GET /webadmin/api/blocks/{block}

Esempio di Content Validate / Apply

Lo stesso payload può essere inviato a entrambi gli endpoint:

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

Esempio di bozza di homepage marketing in inglese:

{
  "plan": {
    "site": "example-site",
    "locale": "en",
    "layout": "default",
    "page": {
      "title": "Acme Studio",
      "path": "/",
      "status": "draft"
    },
    "slots": {
      "main": [
        {
          "type": "section",
          "children": [
            {
              "type": "container",
              "children": [
                {
                  "type": "content_header",
                  "translations": {
                    "title": "Plan, build, and publish with confidence",
                    "subtitle": "Structured content for modern teams",
                    "content": "Create a draft homepage from a validated content plan."
                  }
                },
                {
                  "type": "cluster",
                  "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": "section",
          "children": [
            {
              "type": "container",
              "children": [
                {
                  "type": "cta",
                  "translations": {
                    "title": "Ready to shape the next page?",
                    "content": "Use structured plans for repeatable content creation."
                  }
                },
                {
                  "type": "cluster",
                  "children": [
                    {
                      "type": "button_link",
                      "translations": {
                        "title": "Contact us"
                      },
                      "settings": {
                        "url": "/contact",
                        "variant": "primary"
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

Regole di validazione

  • plan che API non comprende vengono rifiutati con 422 e il codice stabile unsupported_plan_fields e il percorso dell'errore nomina ciascuno di essi; il set di chiavi accettato rientra nell'ambito del piano mode, quindi una chiave significativa in una modalità viene comunque rifiutata in un'altra
  • L'handle o l'ID del sito deve essere risolto
  • la locale deve esistere ed essere abilitata per il sito di destinazione
  • il layout deve esistere
  • Creazione della pagina dei blocchi di conflitto del percorso
  • Il tipo di blocco deve essere pubblicato e utilizzabile
  • Il supporto figlio deve seguire i contratti di blocco, ove disponibili
  • Gli alberi di blocchi del piano di contenuto
  • devono utilizzare children nidificati; i campi di relazione flat id, parent_id, block_id, slot_type_id e block_type_id vengono rifiutati perché API possiede gli ID del database e l'assegnazione padre
  • blocco translations deve contenere chiavi di campo dirette per la locale del piano selezionato, come title, subtitle e content; forme con chiave locale come translations.en.title vengono rifiutate invece di essere ignorate silenziosamente
  • blocchi wrapper come section, container, stack, split, cluster, grid, card, card_body, card_footer, sticky-navbar e sidebar-navigation devono includere blocchi secondari in modo che non possano essere convalidati come Chrome pubblici vuoti; split richiede esattamente due figli diretti e entrambi i lati possono essere nidificati stack
  • Il testo rivolto all'utente appartiene alle righe di traduzione
  • Le impostazioni condivise rimangono condivise
  • nuovo o le impostazioni principali modificate devono corrispondere allo schema di creazione per blocco scoperto; i campi sconosciuti e i valori non validi vengono rifiutati con i percorsi dei campi
  • le impostazioni storiche sconosciute rimangono leggibili e sopravvivono agli aggiornamenti non correlati; un valore esatto invariato può accompagnare PATCH ma non autorizza la modifica di un campo non dichiarato
  • applica convalida nuovamente prima di scrivere
  • l'applicazione è transazionale
  • L'applicazione del contenuto rifiuta ancora la pubblicazione, il sito operazioni di creazione, importazione di contenuti multimediali, recupero remoto, sovrascrittura non supportata, sostituzione ed eliminazione non supportata
  • Shared Slot la creazione rimane di sola creazione a meno che una fase successiva non aggiunga contratti espliciti di mutazione draft-safe
  • gli endpoint delle risorse degli elementi di navigazione supportano operazioni esplicite di aggiornamento, visibilità, riordino ed eliminazione al di fuori del contenuto si applicano con funzionalità protezioni

Forma della risposta

Le risposte devono essere JSON prevedibile:

{
  "ok": true,
  "writes": [],
  "data": {
    "page": {
      "id": 123,
      "title": "Product Overview",
      "status": "draft",
      "edit_url": "/webadmin/pages/123/edit"
    }
  },
  "normalized_plan": {},
  "renderability": {
    "root_blocks": 3,
    "total_blocks": 12,
    "html_blocks": 0,
    "wrapper_blocks_without_children": 0,
    "text_blocks_without_visible_content": 0,
    "button_blocks_without_label_or_url": 0
  },
  "warnings": [],
  "errors": []
}

Gli errori di validazione devono includere un path e un messaggio:

{
  "ok": false,
  "writes": [],
  "data": null,
  "normalized_plan": {},
  "renderability": {
    "root_blocks": 2,
    "total_blocks": 3,
    "html_blocks": 0,
    "wrapper_blocks_without_children": 1,
    "text_blocks_without_visible_content": 0,
    "button_blocks_without_label_or_url": 0
  },
  "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."
    }
  ]
}

Includi edit_url dove utile per le risorse CMS create o aggiornate.

renderability è un riepilogo della validità del piano per gli strumenti IA/operatore. Un piano di pagina strutturato di successo dovrebbe normalmente avere wrapper_blocks_without_children, text_blocks_without_visible_content e button_blocks_without_label_or_url in 0. html_blocks sopra 0 significa che il piano utilizzava la botola di fuga Trusted HTML; gli strumenti dovrebbero farlo solo con l'approvazione esplicita dell'operatore e solo quando i tipi di blocco di prima classe non possono rappresentare il contenuto.

Sezioni Aggiuntive Del Piano

I piani di contenuto possono includere navigation_menus, shared_slots e page_slot_shared_slots accanto al piano pagina/slot già esistente. validate non scrive nulla. apply scrive tutte le sezioni valide in un'unica transazione e annulla l'intero piano quando una sezione successiva fallisce.

{
  "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
          },
          {
            "label": "About",
            "link_type": "page",
            "page_id": 9
          },
          {
            "label": "Docs",
            "link_type": "group",
            "children": [
              { "label": "Intro", "url": "/docs/intro" },
              { "label": "Guide", "url": "/docs/guide" }
            ]
          }
        ]
      }
    ],
    "shared_slots": [
      {
        "handle": "site-header",
        "label": "Site Header",
        "slot": "header",
        "blocks": []
      }
    ],
    "page_slot_shared_slots": [
      {
        "page": "created",
        "slot": "header",
        "shared_slot": "site-header"
      }
    ]
  }
}

Gli elementi di navigazione contengono link_type: custom_url (l'impostazione predefinita richiede un percorso interno sicuro o un URL http(s)), page (richiede page_id per una pagina sullo stesso sito; l'etichetta ricade sul nome della pagina) o group (un'etichetta che apre i suoi figli e non contiene URL). Solo uno group accetta children, che vengono creati con il loro parent_id già collegato, quindi un menu a discesa è un piano anziché uno POST più uno PATCH per articolo. I piani di contenuto nidificano su un livello; gli alberi più profondi utilizzano POST /navigation-menus/{menu}/items. Uno link_type non supportato viene rifiutato per nome invece di essere costretto a custom_url.

page_slot_shared_slots[].page può fare riferimento alla pagina creata dallo stesso piano utilizzando created o a un ID pagina esistente. shared_slot può fare riferimento a uno Shared Slot creato in precedenza nello stesso piano o a un handle Shared Slot esistente sullo stesso sito.

I piani di contenuto salvano una versione della pagina completata dopo tutte le scritture dei blocchi e le assegnazioni Shared Slot e una versione completata per ogni Shared Slot appena creato. I piani di assegnazione delle pagine esistenti salvano una versione di sicurezza precedente alla modifica per ogni pagina interessata. La sostituzione degli slot e la promozione graduale mantengono i loro espliciti controlli di sicurezza. Un'acquisizione consecutiva senza modifiche riutilizza l'ultima istantanea completa e registra un evento di acquisizione separato; le richieste HTTP indipendenti rimangono operazioni separate. Le letture dei dettagli della versione includono inspection.capture_history delimitato contenente eventi di acquisizione recenti e un flag has_more. Vedi Revisioni.

Immagini mobili opzionali (1.91.0)

slide, image, hero, section, card, cta, content_header e link-list-item accettano un mobile_media_id di livello superiore contenente un ID libreria multimediale immagine nei piani di contenuto e PATCH /blocks/{block}. La relazione è archiviata in block_media con il ruolo mobile_image ed è condivisa tra le impostazioni locali. Omettere il campo in PATCH per preservarlo; invia null per cancellarlo.

A Con larghezze del viewport fino a 768 px, un'immagine mobile pubblica sostituisce l'immagine predefinita. Se è assente, cancellato o privato, il renderer mantiene l'impostazione predefinita. Le immagini in primo piano utilizzano una sorgente picture reattiva; i blocchi di sfondo cambiano il loro sfondo CSS. Utilizza un ritaglio diverso dello stesso oggetto visivo perché il testo alternativo, la didascalia, la posizione, l'adattamento, la sovrapposizione e il collegamento rimangono condivisi. Il Visualizzatore galleria del blocco Immagine apre ancora l'immagine predefinita a piena risoluzione. Gli elementi della galleria, i loghi dei marchi, i video e l'audio non accettano questo campo.

{
  "locale": "en",
  "mobile_media_id": 456
}

Slide e Slider settings.content_position supportano nove valori da 1.91.1: center, center-left, center-right, top-left, top-center, top-right, bottom-left, bottom-center e bottom-right.

Indicazioni per l'uso con l'IA

  • individuate prima siti, lingue (locale), layout e tipi di blocco
  • validate prima di applicare
  • create contenuti in bozza
  • preferite i blocchi strutturati indicati in docs/public-block-render-markup.md
  • evitate Safe HTML se non come ripiego verificato
  • mantenete i testi pubblici generati nella lingua di destinazione, ad esempio l'inglese per una homepage in inglese

Confini

  • nessuna integrazione OpenAI o LLM nel core del CMS
  • nessun crawling o recupero di contenuti
  • nessuna sostituzione arbitraria di import/export
  • nessuna pubblicazione automatica
  • nessuna eliminazione distruttiva nella fase 1
  • nessun presupposto sulla rotta /admin dell'host
  • nessun uso del prefisso di rotta /cms
  • nessun codice runtime specifico di QuizTem; la generazione della homepage di QuizTem è un caso d'uso successivo di questa API CMS generica

Stato del sistema dell’intera installazione

Poiché CMS 1.98.0, GET /webadmin/api/system/health restituisce { "ok": true, "health": { ... } } tramite la funzionalità esplicita system-health.read. È accettato solo un token di sistema senza restrizioni con un creatore attivo che attualmente ha accesso al sistema. Sono esclusi i token personali, revocati, scaduti e con ambito sito; la funzionalità non è inclusa nel set di creazione del contenuto predefinito.

Opzionale site_id deve identificare un sito esistente. Filtra i controlli del sito, della ricerca e del lavoro programmato mentre i controlli a livello di installazione rimangono nella risposta. Il rapporto include checked_at, scheduler_checked_at, prove dal vivo scheduler, cache_seconds (300), selected_site_id, site_options, sites, categories, counts, issues ordinato in base alla gravità, Informazioni di sistema information e operations recente. Gli stati di controllo sono healthy, warning, critical, unknown e not_applicable. I controlli espongono uno code stabile, una chiave di traduzione controllata message e parameters, oltre all'amministratore route e route_parameters per il follow-up.

L'oggetto scheduler contiene i timestamp status, scheduler_status, notification_status, UTC last_seen_at, last_completed_at e last_failed_at, stale_after_seconds (300) e required derivati dai siti filtrati. La lettura riutilizza l'istantanea panoramica di cinque minuti e legge in tempo reale le prove registrate dallo scheduler. Non contatta il server di rilascio né esegue la manutenzione. Le prove mancanti vengono segnalate come sconosciute o non applicabili a seconda che il sito richieda o meno una pianificazione. La disponibilità dell'archivio non certifica l'integrità del ripristino; la copertura della ricerca non certifica l'aggiornamento del testo indicizzato. I risultati dell'operazione omettono registri, riepiloghi grezzi, percorsi di archivio e testo delle eccezioni. Vedere Operazioni per la panoramica rivolta all'operatore.

Aggiornamenti di sistema a livello di installazione

Dalla 1.90.0, concesso esplicitamente system-updates.read e Le funzionalità system-updates.run espongono controlli di aggiornamento, approvati in modo sincrono esecuzione e risultati operativi durevoli. I token personali e con ambito sito lo sono escluso. Segui il contratto API Aggiornamenti di sistema per l'approvazione esatta della versione/checksum, l'idempotenza e il ripristino della perdita di connessione.

Criterio di notifica dei messaggi del sito condiviso (CMS 1.95.0)

GET /webadmin/api/sites/{site}/notifications richiede content.read e restituisce notification_settings risolto, delivery_status aggregato per gli eventi di messaggio negli ultimi trenta giorni e gli ultimi risultati summary_delivery_status. Ogni richiesta applica le restrizioni del sito token; i token delegati mantengono anche l'attuale accesso al sito del proprietario.

PATCH /webadmin/api/sites/{site}/notifications richiede site-settings.write. Questa è un'impostazione dell'operatore, indipendente dalla modifica del contenuto del blocco. Unisce i campi forniti, conserva le impostazioni omesse e rifiuta i campi sconosciuti, valori nulli e non supportati.

{
  "notification_mode": "alert_only",
  "notification_frequency": "batched",
  "batch_minutes": 10,
  "daily_summary": true,
  "summary_hour": 9
}

I valori supportati sono full/alert_only e immediate/batched/daily; gli intervalli batch sono compresi tra 1 e 60 minuti e le ore giornaliere sono comprese tra 0 e 23 nel fuso orario del sito. Le notifiche di solo avviso escludono contenuti, indirizzi, oggetti, intestazioni e allegati derivati ​​dai visitatori. I riepiloghi giornalieri contengono sempre solo conteggi e collegamenti alla posta in arrivo protetta. Lo scheduler host Laravel elabora batch e riepiloghi ogni minuto; le notifiche non garantiscono l'accesso alla posta in arrivo.

Live Chat 0.7.0 espone la policy ereditata come notification_policy nelle letture e nelle scritture delle impostazioni. Configura i suoi notify_offline_messages e notification_email tramite l'API delle impostazioni del plugin; modificare la privacy e la frequenza tramite l'endpoint del sito condiviso. I tentativi di sovrascrivere la policy condivisa tramite l'endpoint del plug-in vengono rifiutati. Altri plugin abilitati possono essere integrati tramite il contratto adattatore SiteNotificationChannel di proprietà del prodotto.

Integrità dello scheduler (CMS 1.95.1)

La risposta GET del criterio di notifica include anche scheduler_health, con status, scheduler_status, notification_status, last_seen_at, last_completed_at, last_failed_at, stale_after_seconds (300) e il booleano required derivato dalla politica del sito. Gli stati distinguono healthy, unverified, delayed, running, failed e unavailable. I timestamp sono UTC e contengono solo prove di esecuzione; Le letture API non generano un heartbeat né modificano le impostazioni. I controlli di portata e capacità rimangono invariati.

A sono necessarie la richiamata pianificata recente e l'esecuzione della notifica completata per verificare lo stato di integrità. L'invio manuale viene registrato separatamente e non può certificare la pianificazione. Le impostazioni del dashboard/sito avvisano quando i criteri di notifica del sito richiedono la pianificazione ma il runtime registrato non è verificato, è ritardato, non è riuscito o non è disponibile. Le risposte alle impostazioni della Live Chat 0.7.1 e lo stato del plugin utilizzano le stesse prove registrate. I requisiti generali di configurazione e la proprietà dell'amministratore del server sono descritti in Installazione.

Schemi delle impostazioni di creazione per blocco

Per il catalogo completo, la responsabilità dei dati memorizzati e i contratti di rendering, vedere Contratti dei tipi di blocco. Gli schemi completano l’Inventario CMS; non concedono accesso né rendono scrivibile tramite API un blocco riservato alla modifica umana.

Da CMS 1.105.9, il rilevamento dei tipi di blocco e i contratti di contenuto includono un oggetto aggiuntivo authoring_settings_schema. I precedenti formati settings_schema restano invariati. La revisione 1 comprende tutti i blocchi core pubblicati ed espone mode, unknown_fields e fields. Ogni campo descrive tipo, opzioni, limiti di intervallo e lunghezza, cancellazione mediante null o valori vuoti, conservazione dei campi omessi negli aggiornamenti e decisioni separate per writes.admin, writes.create e writes.patch, con l’eventuale motivo closed_reason.

Leggere questi flag di operazione prima di scrivere. Un campo accettato durante la creazione di un blocco non è automaticamente scrivibile tramite PATCH. I campi di consegna/privacy dei contatti mantengono le esclusioni PATCH deliberatamente esistenti, HTML rimane riservato agli utenti umani e i riferimenti ai media utilizzano i campi di relazione dedicati. Gli schemi di campo non concedono autorizzazioni e non eseguono query sui fornitori di contenuti esterni.

I piani di contenuto e il blocco slot POST rifiutano chiavi sconosciute e valori forniti non validi prima della scrittura. PATCH convalida solo le modifiche e le unisce alle impostazioni correnti. Un aligment con errori di ortografia viene rifiutato invece di accettare un valore che non ha alcun effetto visibile; un valore alignment non valido viene rifiutato invece di cancellare silenziosamente la scelta esistente. I valori mancanti non inseriscono valori predefiniti durante gli aggiornamenti. Gli alias di compatibilità dichiarati rimangono supportati: il cursore fade si normalizza in slide, la Galleria masonary in masonry e le chiavi di copia del modulo di contatto esistenti nelle impostazioni di creazione vengono utilizzate dallo scrittore di traduzione locale. PATCH utilizza translations per quella copia. I valori interi non vengono bloccati automaticamente e il testo troppo lungo non viene troncato automaticamente. Le impostazioni predefinite di creazione esistenti come Colonne plain e Dividi stack rimangono.

I valori storici sconosciuti o non corretti rimangono leggibili, vengono visualizzati con i fallback esistenti e sopravvivono agli aggiornamenti non correlati. Un client può trasportare un campo storico identico solo quando il server può confrontarlo con quell'esatto blocco esistente; ciò non autorizza l'aggiunta o la modifica di impostazioni sconosciute. I nuovi blocchi e i payload sostitutivi completi sono di nuova creazione, quindi non possono rivendicare un'eccezione di valore storico. La clonazione affidabile, la gestione temporanea e il ripristino delle revisioni mantengono i percorsi di archiviazione senza perdite.

I plugin senza schemi mantengono il comportamento delle impostazioni esistenti. I plugin possono aderire attraverso la definizione del blocco o manifestare con regole scalari; una dichiarazione non valida blocca la scrittura per quello schema senza bloccare i blocchi core non correlati. Le impostazioni dell'applicazione, le icone attive e i collegamenti Dynamic Content continuano a utilizzare i loro validatori specializzati dopo il controllo del campo comune.

Gli operatori del server possono eseguire php artisan webblocks:blocks:audit-settings per un report di compatibilità di sola lettura prima di creare contenuto esistente. Stampa identità, percorsi e codici dei campi invece dei valori delle impostazioni, esegue la scansione senza riparazioni o richieste del fornitore ed esce da 1 se esistono impostazioni incompatibili. --limit=100 delimita i blocchi segnalati (massimo 1000); il riepilogo conta ancora la scansione completa. Ciò controlla la compatibilità dello schema scalare, non il provider esterno o l'integrità dell'applicazione. I plugin senza schema vengono conteggiati separatamente. Le nuove impostazioni dichiarate modificate sono limitate a 128 campi, 256 KiB, 32 livelli nidificati e 4096 nodi senza applicare tali limiti retroattivamente ai dati storici invariati.