Contenu dynamique : sources, boucles et correspondances des champs

Le contenu dynamique relie les enregistrements d’un fournisseur activé aux blocs habituels du CMS. Le fournisseur gère les données et leurs traductions ; vous gérez la mise en page, le modèle répété et les correspondances. Ce guide décrit le parcours du panneau dans CMS 1.104.0, avec le standard des sources 1.0. L’exemple est le catalogue de plugins publié.

Vous pouvez établir ces connexions sans écrire de requêtes API ni saisir d’identifiants de blocs. L’accès API et les identifiants d’accès relèvent de l’intégration installée ; cet espace sélectionne les sources qu’elle a déjà enregistrées.

Trouver une source et ses utilisations

Ouvrez Contenu dynamique → Sources. Les détails indiquent le fournisseur, l’origine déclarée, le type collection ou enregistrement unique, les langues, la clé stable et les champs disponibles. Une déclaration de langues décrit un contrat ; elle ne confirme pas une connexion réelle réussie.

Les vues Boucles, Liaisons de champs et Problèmes montrent les utilisations. Filtrez par site, état de publication ou recherche. Les nombres comptent les blocs et connexions enregistrés, pas les cartes générées. Ouvrir cet inventaire lit la configuration sans demander de contenu distant. Les utilisations de Shared Slots renvoient vers leur éditeur existant ; le parcours guidé ci-dessous utilise des slots propres à la page.

L’intégration de l’exemple expose trois sources distinctes :

  • Published plugin catalog (webblocks-extensions-live::plugins) : collection destinée aux cartes répétées.
  • Published plugin (webblocks-extensions-live::plugin) : un plugin sélectionné, utilisable comme enregistrement fixe.
  • Catalog interface (webblocks-extensions-live::ui) : l’enregistrement labels fournit les textes d’interface communs traduits.

Ces libellés du fournisseur peuvent rester anglais dans un panneau traduit. Le contenu des enregistrements utilise la langue demandée.

Relier une source à une page

Dans les détails, choisissez Utiliser sur une page. Sélectionnez le site et la page, puis Charger la destination. Pour la collection du catalogue, choisissez Grid comme bloc contenant la boucle. Chargez cette destination, puis choisissez son enfant direct Card comme modèle répété.

Sur une page publiée, vous pouvez immédiatement examiner et prévisualiser les connexions. Avant d’enregistrer, choisissez Préparer un brouillon de mise à jour, puis la destination dans ce brouillon. Les blocs clonés ont leurs propres identifiants : utilisez les sélecteurs visibles et vérifiez les correspondances. La page publiée reste inchangée.

Si le brouillon ne contient aucun modèle adapté, Créer une grille et une carte initiales ajoute un modèle non connecté à un slot propre à la page. Les blocs existants sont conservés ; les champs ne sont pas choisis à votre place. Installation, accès à la source et identifiants API se configurent dans l’intégration du fournisseur, pas ici. Consultez le Système de plugins pour l’installation.

Choisir la boucle et le modèle répété

La boucle appartient au Grid ; la Card est répétée une fois par enregistrement correspondant. Les blocs Image, Header, Plain Text et Button Link à l’intérieur reçoivent l’enregistrement courant. Un Header fixe à côté de la Card reste éditorial et ne peut pas utiliser l’enregistrement courant de cette boucle.

L’arborescence marque le propriétaire de la boucle, le modèle répété et les champs connectés. Les ancêtres repliés signalent un contenu dynamique sous-jacent. Suivez un indicateur vers la boucle ou la correspondance concernée. Une seule Card enregistrée peut ainsi produire dix cartes publiques sans dix copies éditables.

Choisissez un enfant direct compatible, pas un petit-enfant ni un bloc d’une autre page. Section, Container, Stack, Cluster, Grid et Slide acceptent les modèles enfants par ailleurs valides ; Slider exige Slide, Columns exige Column Item, Feature Grid exige Feature Item ou Column Item et Link List exige Link List Item. Card et Split ne proposent pas cette capacité de conteneur de collection.

Section
└─ Container
   └─ Grid  [loop: Published plugin catalog]
      ├─ Header  [fixed editorial block]
      └─ Card  [repeated template]
         ├─ Image
         ├─ Header
         ├─ Plain Text
         └─ Button Link

Configurer filtres, tri et pagination

Pour le catalogue, réglez Nombre maximal d’enregistrements sur 50, Champ de tri sur title, le sens sur croissant et Enregistrements par page sur 12 ; activez Paginer les enregistrements. Cinquante est la limite de résolution, pas la garantie que cinquante enregistrements existent. Dix résultats avec douze par page donnent une seule page d’aperçu. Slider ne prend pas en charge ce contrôle de pagination.

Filtrez uniquement sur les champs déclarés. Published plugin catalog sélectionne déjà les plugins publiés chez le fournisseur ; n’inventez pas de champ status et ne maintenez pas un second filtre de publication dans CMS. Choisissez séparément les comportements Si aucun enregistrement ne correspond et Si la source échoue : masquer le modèle ou conserver sa version éditoriale. Vérifiez les deux avant publication.

Pour les petites collections, CMS filtre et trie les enregistrements renvoyés. Les fournisseurs capables de requêtes les exécutent eux-mêmes. Les détails de la source indiquent le modèle utilisé.

Associer les champs à l’enregistrement courant, fixe ou à la valeur éditoriale

Dans Correspondances des champs du modèle, choisissez le mode de valeur de chaque champ cible :

  • Enregistrement courant de la boucle : les valeurs changent par carte. Sélectionnez la collection et un champ compatible ; l’enregistrement est l’élément courant.
  • Enregistrement fixe de la source : toutes les cartes peuvent partager la valeur d’un même enregistrement. Sélectionnez la source, son enregistrement, puis un champ compatible.
  • Valeur éditoriale / secours : utilise le texte ou média saisi dans le bloc. Si une connexion ne renvoie aucune valeur utilisable, cette valeur éditoriale peut aussi servir de secours.

Par exemple, reliez le titre Header à title, le contenu Plain Text à summary et l’URL Button Link à url de l’enregistrement courant. Pour le libellé du bouton, utilisez la source fixe Catalog interface, enregistrement labels, champ explore. Source, enregistrement et champ ont des sélecteurs distincts ; Rechercher des enregistrements et champs permet de réduire les choix.

Les blocs connectés possèdent aussi un onglet Contenu dynamique dédié. Les valeurs ordinaires des Champs du bloc sont les valeurs éditoriales de secours. Un champ texte ne peut pas choisir un champ exclusivement URL ; les choix courants se limitent à la branche du modèle sélectionné. Avant de modifier ou supprimer une boucle, réaffectez les correspondances concernées : la validation refuse les connexions orphelines ou incompatibles.

Relier séparément image, texte alternatif, légende et lien

La source fournit une URL d’image accessible ou une référence média appartenant à cette installation CMS. L’identifiant numérique d’une image dans une application distante n’est pas automatiquement un identifiant média CMS. CMS affiche l’image avec son bloc Image habituel ; vous ne copiez pas le fichier dans chaque Card.

Pour le bloc Image du catalogue, utilisez quatre connexions indépendantes :

  • Source de l’image → image_url de l’enregistrement courant.
  • Texte alternatif → image_alt.
  • Légende facultative → image_caption.
  • Lien → url.

Un fichier peut être commun à plusieurs langues alors que texte alternatif et légende changent. Le texte alternatif décrit les informations visuelles utiles ; la légende fournit un contexte visible facultatif. Ne copiez pas l’un dans l’autre. Dans l’API, Image subtitle correspond au texte alternatif et Image title à la légende. Vérifiez le chargement et la pertinence des deux textes ; un champ de type URL ne garantit pas une image.

Recevoir les traductions du fournisseur

Le standard 1.0 exige de chaque source les six langues CMS : en, tr, de, es, it et fr, même si un site en active moins. CMS demande la langue activée du site courant ; le fournisseur livre les textes de l’enregistrement, textes alternatifs, légendes et libellés communs correspondants. Vous ne traduisez pas chaque carte générée dans l’éditeur de page.

La même Card utilise par exemple summary en anglais et sa traduction turque fournie à la source lorsque la langue demandée est tr. Le libellé du bouton vient de Catalog interface / labels / explore dans cette même langue. Le fichier image peut rester identique.

Les parties statiques rédigées autour de la boucle conservent les traductions normales des pages et blocs. La validation contrôle marqueurs de langue, clés stables et types, pas la qualité de traduction. Prévisualisez chaque langue activée et examinez le texte réel. Un fournisseur ne doit pas étiqueter de l’anglais inchangé comme une autre langue.

Vérifier l’aperçu configuré avant d’enregistrer

Choisissez Langue de l’aperçu, puis Vérifier la source et prévisualiser. L’aperçu privé dans un nouvel onglet rend le modèle réel avec les correspondances non enregistrées, filtre, tri, limite et pagination actuels. Il n’enregistre ni ne publie la page. Ouvrir seulement les détails de la source n’exécute pas cette vérification.

Confirmez le nombre d’enregistrements, titres, résumés, libellés et destinations des boutons. Vérifiez images chargées, textes alternatifs et légendes traduits. Distinguez un résultat vide valide d’un accès refusé, d’une réponse non conforme au contrat ou d’un fournisseur indisponible. L’aperçu signale ces états séparément. Vérifiez accès ou réglages du fournisseur si nécessaire ; ne remplacez pas les données manquantes par des traductions supposées.

Si vous changez les réglages, générez un nouvel aperçu. Avec la pagination, parcourez les pages pour examiner le résultat configuré. Un échantillon API aide au diagnostic mais ne remplace pas l’aperçu visuel complet de la Card.

Enregistrer un brouillon puis examiner la publication séparément

Enregistrer les connexions du brouillon modifie uniquement le brouillon et crée une révision. Si la page a changé depuis son ouverture, rechargez-la et examinez-la avant d’enregistrer. Une configuration invalide conserve les réglages précédents. Vérifiez à nouveau le brouillon rendu dans toutes les langues activées et utilisez le processus éditorial habituel pour publier ou promouvoir la mise à jour.

Une collection répète des blocs dans une page existante. La destination de détail doit déjà exister ou venir d’une règle de Pages automatiques configurée séparément. Relier une boucle ne crée ni n’active cette règle. Le fournisseur des plugins publiés détermine les enregistrements disponibles ; CMS ne devrait pas entretenir une seconde copie manuelle du catalogue.

Référence technique : standard des sources et contrat d’entité

Un plugin activé enregistre ses sources dans PluginDefinition::contentSources(...). Un résolveur d’entité implémente ContentSourceResolver : options() propose des choix sûrs et lisibles indexés par identité stable ; resolve() renvoie un enregistrement pour le site, la page, la langue et le contexte d’aperçu. Un résolveur de collection implémente ContentCollectionSourceResolver ; les grandes collections peuvent implémenter QueryableContentCollectionSourceResolver avec ContentCollectionQuery et ContentCollectionResult pour les requêtes, totaux et fenêtres de pagination.

La déclaration ci-dessous appartient à l’intégration, pas à l’éditeur. Chaque enregistrement résolu doit inclure _locale égal à la langue demandée, une clé chaîne non vide déclarée par recordKey et tous les champs déclarés. Utilisez null pour les valeurs indisponibles ; les clés de collection doivent être uniques. Les types sont text, rich_text, url ou media. Une valeur media est un identifiant média CMS positif ; les autres valeurs non nulles sont des chaînes. Les URL doivent respecter le contrat URL de la source.

ContentSourceDefinition::collection('catalog::items')
  ->label('Catalog items')
  ->resolver(CatalogItems::class)
  ->standard(
    locales: ['en', 'de', 'tr', 'es', 'it', 'fr'],
    description: 'Localized catalog records.',
    origin: 'Catalog application',
    recordKey: 'id',
  )
  ->fields([
    'id' => ['type' => 'text', 'label' => 'Record ID'],
    'title' => ['type' => 'text', 'label' => 'Title'],
    'image_url' => ['type' => 'url', 'label' => 'Image'],
    'image_alt' => ['type' => 'text', 'label' => 'Alternative text'],
    'image_caption' => ['type' => 'text', 'label' => 'Caption'],
  ]);

Les sources non versionnées sont marquées Héritée — mise à jour du standard requise. Les choix existants peuvent rester inchangés, mais les nouvelles connexions exigent le standard multilingue. Les fournisseurs possèdent tables et enregistrements ; CMS possède mise en page et rendu. Les conteneurs de plugins activent la capacité avec contentCollectionTemplate() et rendent les enfants résolus via ContentCollectionRenderer::children($block) ; les manifestes déclarent content_collection.enabled et éventuellement content_collection.child_types. Les plugins doivent réutiliser les moteurs Card, Grid et Image du noyau.

Référence technique : accès, cache et valeurs de secours

Pour les enregistrements restreints, attachez une ContentSourceAccessPolicy avec accessPolicy(...) ; CMS contrôle site, page, langue, état d’aperçu et acteur authentifié avant résolution. Les échecs d’entité ou valeurs vides conservent le secours éditorial du champ. Les résultats vides d’une collection et erreurs du résolveur sont configurés séparément ; les sources refusées ou retirées conservent l’arborescence enregistrée. Problèmes et les contrôles de bloc identifient les connexions indisponibles sans les supprimer silencieusement.

cacheFor($seconds) active un cache de résultats borné ; zéro, valeur par défaut, le désactive. Les clés incluent source, site, page, langue, arguments d’enregistrement/requête et réglages. L’aperçu ignore ce cache. Après une modification des données métier, appelez app(ContentSourceRuntime::class)->invalidate('plugin-handle::source') pour invalider les variantes de cette source. Duplication, révisions et export/import conservent connexions et configuration de collection ; les résultats exécutés du fournisseur ne sont pas copiés dans ces paquets.

Référence technique : Internal Content API

GET /webadmin/api/content-sources découvre les sources activées accessibles. Ajoutez block_id pour examiner cibles compatibles et capacité de collection. POST /webadmin/api/content-sources/{source}/preview résout une entité sélectionnée ou au plus cinq échantillons de collection, en exposant uniquement les champs déclarés. Cet endpoint d’échantillons ne rend pas tout le modèle configuré.

PATCH /webadmin/api/blocks/{block} accepte content_bindings et content_collection au premier niveau ou sous settings. Chaque objet remplace la configuration correspondante ; null l’efface. La validation couvre accès, choix des enregistrements, types, appartenance des enfants directs et capacité du modèle. Les requêtes invalides renvoient 422 invalid_content_source_configuration. Utilisez un brouillon ou brouillon de mise à jour qui vous appartient, puis rendez le résultat ; suivez les règles d’autorisation et publication de Internal Content API. Image subtitle et title conservent leurs sens distincts de texte alternatif et de légende.