Contrats de types de bloc
Objectif et périmètre
Ce document a débuté comme l'inventaire de la phase 1 des types de bloc core publiés actuellement livrés dans WebBlocks CMS ; il documente désormais aussi la vue de contrat en lecture seule de l'administration issue de la phase 2 et consigne les correctifs de standardisation des écarts de la phase 3 réalisés à ce jour, y compris le nettoyage Layout + Card pour section, container, grid, cluster, card et content_header, le nettoyage Marketing / Contenu structuré pour hero, columns, column_item, cta, feature-grid et feature-item, ainsi que le nettoyage Legacy / Transitional qui garde les anciens slugs de compatibilité documentés honnêtement sans les promouvoir dans le catalogue core publié.
La phase 1 est uniquement une documentation en lecture seule.
- Elle ne repense pas les formulaires de bloc.
- Elle n'ajoute pas de générateur de formulaires piloté par la base de données.
- Elle ne migre pas le contenu des blocs.
- Elle ne modifie pas le rendu public.
- Elle ne modifie pas le fonctionnement actuel des modifications dans
Admin -> System -> Block Types.
L'écran d'administration Block Types actuel reste un écran de catalogue et de métadonnées. En phase 2, il peut désormais ouvrir une fenêtre modale Contract en lecture seule pour chaque ligne listée, mais il n'est toujours ni un générateur de formulaires dynamique ni un éditeur de schémas.
La phase 3 des plugins ajoute des hooks de bloc de plugin purement déclaratifs via PluginBlockTypeDefinition, PluginBlockPackDefinition et PluginBlockRegistry. Les plugins activés peuvent exposer des handles appartenant au plugin, tels que analytics-tools::score-card, à des fins de découverte, mais ces déclarations ne remplacent pas les contrats de bloc core livrés, les vues de bloc core, les seeders core ni les services d'édition de blocs. Les handles non qualifiés de style core, tels que hero, restent la propriété du core et sont rejetés pour les déclarations de plugins.
Définition
Un contrat de type de bloc est l'accord technique actuel décrivant le comportement d'un type de bloc à travers les différentes couches du CMS :
- identité de catalogue : slug, libellé, catégorie, statut et métadonnées de système ou de conteneur
- source du formulaire d'administration : quel partiel Blade édite actuellement le bloc et quels champs il expose
- validation et traitement des requêtes : comment
App\Http\Requests\Admin\BlockRequestnormalise et valide actuellement les charges utiles des blocs - propriété du stockage : quelles valeurs résident dans
blocks, dans des lignes de traduction dédiées, dansblock_mediaou dans des enregistrements liés - propriété de la traduction : quels champs destinés à l'utilisateur appartiennent à la langue
- propriété partagée : quels réglages ou relations restent partagés entre les langues
- propriété des médias ou des relations :
media_iddirect,block_mediaordonné, recherches de navigation ou relations au sein d'une même page - prise en charge des enfants : si le bloc est un conteneur et si les types enfants sont restreints
- source du moteur de rendu public : quel partiel Blade public rend le bloc aujourd'hui
- contrat de racine du moteur de rendu : si le bloc possède son propre balisage racine public ou s'appuie sur le chemin générique du wrapper
- portabilité et révisions : si la forme de stockage actuelle doit continuer à circuler à travers les révisions, le clonage, l'export/import et la promotion
- tests et écarts : couverture ciblée connue, comportement peu clair ou dette de compatibilité
Termes du contrat actuel
Termes de statut utilisés ci-dessous :
clear: le formulaire d'administration, le traitement des requêtes, le stockage et le moteur de rendu concordent pour l'essentielmostly clear: le contrat actuel est compréhensible mais comporte une réserve notabletransitional: le contrat actuel conserve intentionnellement un chemin de compatibilité ou un modèle de propriété mixteneeds review: les chemins de code actuels divergent ou le comportement est suffisamment peu documenté pour que la phase 2 doive le mettre en évidence plus clairementlegacy/fallback: le comportement publié dépend d'un chemin de repli ou de compatibilité
Règles de propriété du stockage
Les travaux actuels et futurs sur les contrats doivent garder ces règles de propriété explicites :
- le texte destiné à l'utilisateur appartient aux lignes de traduction lorsque le bloc appartient à une langue
- les données opérationnelles ou de réglage partagées appartiennent aux réglages partagés du bloc ou à des relations explicites
- les médias doivent utiliser les chemins de propriété
media_idoublock_medialorsque cela s'applique - évitez de déplacer du contenu destiné à l'utilisateur vers un JSON de réglages arbitraire
- gardez les chemins de stockage de compatibilité documentés tant qu'ils influent encore sur la sortie publique ou les imports
Sources livrées
Cet inventaire de la phase 1 s'appuie sur le code source livré, et non sur des suppositions.
- source du catalogue :
app/Support/Blocks/CoreBlockTypeCatalogSyncer.php - normalisation de la requête d'édition de bloc :
app/Http/Requests/Admin/BlockRequest.php - utilitaires de persistance :
app/Support/Blocks/BlockPayloadWriter.php,app/Support/Blocks/BlockTranslationWriter.php,app/Support/Blocks/BlockTranslationResolver.php - registre des traductions :
app/Support/Blocks/BlockTranslationRegistry.php - formulaires d'administration :
resources/views/admin/blocks/types/*.blade.php - moteurs de rendu publics :
resources/views/pages/partials/blocks/*.blade.php - références de couverture : tests de catalogue de blocs, de rendu, de traduction et spécifiques aux slugs dans
tests/Feature/
Types de bloc core publiés actuellement documentés ici : 42.
Commande d'audit
La phase 1 ajoute une commande d'audit sans risque destinée aux développeurs :
php artisan block-types:contracts-audit
php artisan block-types:contracts-audit --json
La commande est en lecture seule.
- elle ne modifie pas la base de données
- elle ne dépend pas du contenu du site installé
- elle lit les définitions du catalogue core livré
- elle vérifie la présence des fichiers de formulaire d'administration et de moteur de rendu public livrés
- elle rend compte des métadonnées de famille de traduction et de la prise en charge de base des conteneurs
La commande est une aide à l'actualisation permettant de repérer les écarts de catalogue et de présence de fichiers. Elle ne remplace pas les notes de contrat plus complètes de ce document.
Vue d'administration de la phase 2
La phase 2 expose les détails du contrat en lecture seule dans Admin -> System -> Block Types.
- chaque ligne peut ouvrir une fenêtre modale
Block Type Contract - la fenêtre modale est purement informative et ne soumet aucune mise à jour
- elle affiche les détails de catalogue, de formulaire d'administration, de stockage, de traduction, de médias ou de relations, d'enfants, de moteur de rendu et d'écarts à partir du code livré
- elle ne transforme pas l'administration Block Types en éditeur de schémas ou en générateur de formulaires
- les types de bloc personnalisés ou en brouillon peuvent également ouvrir la fenêtre modale, mais peuvent afficher
No shipped contract is documented for this block type yet.lorsqu'aucun contrat core n'est défini
Matrice des contrats de blocs publiés
Contenu
| Slug | Label | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglages | Champs médias/relations | Comportement enfant/conteneur | Source du moteur de rendu public | Contrat de la racine du moteur de rendu | État actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| header | Header | content | resources/views/admin/blocks/types/header.blade.php | title via les lignes de traduction de texte | variant niveau de titre ; settings.alignment ; ancre partagée dans settings.anchor avec repli hérité sur url | Le sommaire de la même page lit les blocs Header dotés d'une ancre | N'est pas un conteneur | resources/views/pages/partials/blocks/header.blade.php | Possède son propre élément de titre racine | clear | SyncCoreBlockTypesCommandTest, PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | Bloc de titre canonique ; le contrat de l'ancre partagée est clair, mais conserve encore le comportement de repli hérité sur url. |
| plain_text | Plain Text | content | resources/views/admin/blocks/types/plain_text.blade.php | content via les lignes de traduction de texte | settings.alignment | Aucun | N'est pas un conteneur | resources/views/pages/partials/blocks/plain_text.blade.php | Possède son propre racine | clear | PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | Primitive simple de texte courant traduit. |
| rich-text | Rich Text | content | resources/views/admin/blocks/types/rich-text.blade.php | content via les lignes de traduction de texte | Aucun | Aucun | N'est pas un conteneur | resources/views/pages/partials/blocks/rich-text.blade.php | Possède sa racine .wb-rich-text lorsqu'un contenu existe | clear | RichTextBlockTest, PublicRichContentTest, BlockTranslationIntegrityTest | Le stockage HTML sûr et la propriété de la traduction sont clairs. |
| code | Code | content | resources/views/admin/blocks/types/code.blade.php | title, subtitle, content via les lignes de traduction de texte | settings.language | Aucun | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/code.blade.php | Possède sa racine | clear | PublicRichContentTest, BlockTypePhaseThreeContractsTest, PageBuilderExperienceTest | La Phase 3 aligne le titre traduit du code, le libellé et le corps de l'extrait sur l'architecture de traduction de texte existante, et ignore désormais les arbres d'enfants historiques arbitraires dans la sortie publique. |
| button_link | Button Link | content | resources/views/admin/blocks/types/button_link.blade.php | le libellé title via les lignes de traduction de texte | settings.url ; settings.target ; variant partagé | Aucun | N'est pas un conteneur | resources/views/pages/partials/blocks/button_link.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest | L'URL et la cible partagées, associées au libellé traduit, sont cohérentes. |
| card | Card | layout | resources/views/admin/blocks/types/card.blade.php | Aucun | settings.layout_name | Les blocs enfants de région définissent la structure ; aucun contrat direct de média ou de traduction | Conteneur ; les seuls enfants directs autorisés sont card_header, card_body et card_footer | resources/views/pages/partials/blocks/card.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest, BlockTranslationIntegrityTest, MediaVisualBlockContractsTest | Card est désormais une coque composable. Elle possède la racine de la carte, efface à l'enregistrement les champs hérités de contenu ou de média et ne conserve qu'un repli de rendu hérité minimal pour les anciennes lignes enregistrées dépourvues d'enfants de région Card. |
| card_header | Card Header | layout | resources/views/admin/blocks/types/card_header.blade.php | Aucun | settings.layout_name | Uniquement la relation avec le card parent | Conteneur ; ne peut être placé que sous card ; les enfants de région de carte ne sont pas autorisés | resources/views/pages/partials/blocks/card_header.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Bloc de région Card composable pour le contenu d'en-tête. |
| card_body | Card Body | layout | resources/views/admin/blocks/types/card_body.blade.php | Aucun | settings.layout_name | Uniquement la relation avec le card parent | Conteneur ; ne peut être placé que sous card ; les enfants de région de carte ne sont pas autorisés | resources/views/pages/partials/blocks/card_body.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Bloc de région Card composable pour le contenu principal. |
| card_footer | Card Footer | layout | resources/views/admin/blocks/types/card_footer.blade.php | Aucun | settings.layout_name | Uniquement la relation avec le card parent | Conteneur ; ne peut être placé que sous card ; les enfants de région de carte ne sont pas autorisés | resources/views/pages/partials/blocks/card_footer.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Bloc de région Card composable pour le pied de carte ou les contenus d'action. |
| stat-card | Stat Card | content | resources/views/admin/blocks/types/stat-card.blade.php | title, subtitle, content via les lignes de traduction de texte | L'url canonique reste partagée sur la ligne du bloc | Aucun | N'est pas un conteneur | resources/views/pages/partials/blocks/stat-card.blade.php | Possède sa racine de stat-card | clear | StatCardTest, BlockTranslationIntegrityTest | La Phase 3 conserve le champ URL facultatif existant et affiche désormais un simple lien public lorsqu'il est renseigné. |
| image | Image | content | resources/views/admin/blocks/types/image.blade.php | caption, alt text via les lignes de traduction d'image | media_id partagé ; url canonique partagée | Relation directe avec le média image via media_id | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/image.blade.php | Possède sa racine sémantique lorsque le média existe | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest, BlockTranslationIntegrityTest | La Phase 3 aligne Image sur l'architecture de traduction d'images existante : la légende et le texte alternatif appartiennent à chaque langue, tandis que le média sélectionné et l'URL de lien facultative restent partagés. |
| gallery | Gallery | content | resources/views/admin/blocks/types/gallery.blade.php plus resources/views/admin/blocks/types/partials/gallery-items-editor.blade.php | Pour chaque élément de galerie : alt_text, caption, overlay_title et overlay_text via block_gallery_item_translations | Réglages de présentation de la galerie partagés, plus les relations ordonnées block_media des éléments de galerie | Lignes block_media ordonnées avec le rôle gallery_item ; le texte des éléments de galerie propre à chaque langue se trouve dans block_gallery_item_translations ; d'anciennes valeurs title/subtitle enregistrées sur le bloc peuvent subsister, mais le rendu public les ignore | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/gallery.blade.php | Possède la racine de son conteneur de galerie et enregistre une seule fenêtre modale de visionneuse sous #wb-overlay-root lorsque la lightbox est activée | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest, PageBuilderExperienceTest, SiteCloneServiceTest, SiteExportImportTest, SitePromotionTest, ReconstructionIntegrityTest, SharedSlotRevisionTest | Gallery est désormais un bloc de collection de médias. Le formulaire d'administration normal utilise un éditeur compact en lignes plutôt que l'ancienne grille de ressources sélectionnées. Son sélecteur imbriqué Add Gallery Items reste sur le contrat d'administration partagé #wb-overlay-root, afin que WebBlocks UI gère le cycle de vie des fenêtres modales empilées, et les longues listes de résultats compactes conservent une hauteur de ligne naturelle tandis que le corps de la fenêtre modale demeure le conteneur de défilement. Les variantes publiques sont distinctes : grid conserve des cellules égales, masonry utilise des colonnes CSS avec une hauteur d'image naturelle et collage conserve la composition avec l'élément mis en avant en premier. Les anciennes valeurs masonary enregistrées sont toujours acceptées et normalisées vers le chemin canonique masonry. Gallery ne produit plus de titre ni de paragraphe d'introduction ; les éditeurs doivent placer content_header plus plain_text ou rich-text avant Gallery lorsqu'un texte de section est nécessaire. Les éléments de repli hérités fondés sur les réglages restent lisibles pour les anciens contenus. |
| download | Download | content | resources/views/admin/blocks/types/download.blade.php | title, subtitle via les lignes de traduction de texte | media_id partagé ; variant partagé | Relation directe avec le fichier de téléchargement via media_id | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/download.blade.php | Possède la racine de son conteneur de CTA lorsque le média existe | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest | La Phase 3 garde partagés le média de téléchargement sélectionné et la variante du bouton, tout en déplaçant le libellé visible et le texte d'aide vers le chemin de traduction de texte existant. |
| file | File | content | resources/views/admin/blocks/types/file.blade.php | title, content via les lignes de traduction de texte | media_id partagé ; url canonique partagée | Relation directe avec le média via media_id, avec repli sur une URL externe | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/file.blade.php | Possède sa racine de carte de fichier | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest | La Phase 3 industrialise le moteur de rendu File déjà livré avec un formulaire d'administration dédié et rend explicite la propriété partagée de la source du fichier entre la médiathèque et le repli sur une URL externe. |
| video | Video | content | resources/views/admin/blocks/types/video.blade.php | title, content via les lignes de traduction de texte | media_id partagé ; url canonique partagée | Relation directe avec le média via media_id, avec repli sûr sur une URL externe | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/video.blade.php | Possède sa racine de carte vidéo | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest | La Phase 3 ajoute le formulaire d'administration et le chemin d'enregistrement manquants, de sorte que la vidéo téléversée, les URL sûres de fournisseurs externes, le texte visible traduit et le comportement public de repli décrivent désormais le même contrat. |
| audio | Audio | content | resources/views/admin/blocks/types/audio.blade.php | title, content via les lignes de traduction de texte | media_id partagé ; url canonique partagée | Relation directe avec le média via media_id, avec repli sur une URL externe | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/audio.blade.php | Possède sa racine de carte audio | clear | MediaVisualBlockContractsTest, PublicMediaBlocksTest | La Phase 3 ajoute le formulaire d'administration et le chemin d'enregistrement manquants, de sorte que l'audio téléversé, le texte visible traduit et un rendu sûr sans contrôles vides correspondent désormais au contrat documenté. |
| table | Table | content | resources/views/admin/blocks/types/table.blade.php | title, content via les lignes de traduction de texte | variant partagé ; le moteur de rendu vérifie aussi le repli settings.rows | Aucun | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/table.blade.php | Possède la racine de son conteneur de tableau | mostly clear | PublicRichContentTest, BlockTypePhaseThreeContractsTest, PageBuilderExperienceTest | La Phase 3 aligne la propriété du titre traduit et du texte des lignes sur l'architecture de traduction de texte existante et ignore désormais les arbres d'enfants historiques arbitraires dans la sortie publique ; le chemin de repli hérité settings.rows reste documenté. |
| quote | Quote | content | resources/views/admin/blocks/types/quote.blade.php | Aucun dans le registre actuel | title, subtitle, content et variant canoniques | Aucun | N'est pas un conteneur ; les lignes enfants historiques sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/quote.blade.php | Possède sa racine de citation | clear | PublicRichContentTest, PageBuilderExperienceTest | La Phase 3 cesse de traiter Quote comme un conteneur ou un wrapper de mise en page dans la sortie publique, tout en préservant les lignes enfants déjà enregistrées dans les arbres de blocs côté administration. |
| hero | Hero | content | resources/views/admin/blocks/types/hero.blade.php | title, subtitle, content via les lignes de traduction de texte | variant partagé ; settings.layout ; settings.title_tag | Blocs button enfants pour les CTA gérés | Conteneur ; uniquement des enfants button | resources/views/pages/partials/blocks/hero.blade.php | Possède sa racine promotionnelle | transitional | PublicHeroBlockRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Hero est désormais un contrat fondamental publié et adossé à du code livré. Le texte d'introduction appartient à chaque langue, les libellés des CTA sont traduits sur les boutons enfants et les URL des CTA restent partagées. Les replis hérités de contenu restent lisibles lorsque les champs traduits canoniques sont vides. |
| columns | Columns | content | resources/views/admin/blocks/types/columns.blade.php | title, subtitle, content via les lignes de traduction de texte | variant partagé | Blocs column_item enfants | Conteneur ; uniquement des enfants column_item | resources/views/pages/partials/blocks/columns.blade.php | Possède sa racine de contenu structuré | clear | PublicColumnsRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Columns est désormais un bloc de contenu structuré publié et de premier ordre. Le texte d'introduction appartient à chaque langue, tandis que la variante, l'ordre des enfants et les URL des enfants restent partagés. |
| column_item | Column Item | content | resources/views/admin/blocks/types/column_item.blade.php | title, subtitle, content via les lignes de traduction de texte | url canonique partagée | Relation avec le columns parent | N'est pas un conteneur | resources/views/pages/partials/blocks/column_item.blade.php | La racine de l'élément est déterminée par le parent et varie selon la variante de Columns | clear | PublicColumnsRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Column Item est désormais un contrat enfant de soutien publié pour Columns. Les modifications par langue mettent à jour le texte de l'élément sans écraser les URL partagées. |
| cta | CTA | content | resources/views/admin/blocks/types/cta.blade.php | title, subtitle, content via les lignes de traduction de texte | variant partagé | Blocs button enfants pour les CTA gérés | Conteneur ; uniquement des enfants button | resources/views/pages/partials/blocks/cta.blade.php | Possède sa racine promotionnelle | clear | PublicHeroBlockRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | CTA est désormais un contrat promotionnel publié, avec un texte et des libellés de CTA propres à chaque langue, des URL de CTA partagées et un moteur de rendu public qui possède sa racine. |
| feature-grid | Feature Grid | content | resources/views/admin/blocks/types/feature-grid.blade.php | title, subtitle, content via les lignes de traduction de texte | Aucun au-delà de la structure d'enfants partagée | Blocs feature-item enfants, avec prise en charge compatible de l'ancien column_item | Conteneur ; les enfants autorisés sont feature-item et column_item | resources/views/pages/partials/blocks/feature-grid.blade.php | Délègue à la présentation en cartes de Columns et utilise toujours le conteneur public générique | transitional | PublicHeroBlockRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Feature Grid est désormais un alias de compatibilité publié, car il dispose de véritables chemins d'administration et de rendu livrés, mais il continue délibérément de déléguer au contrat en cartes de Columns. |
| feature-item | Feature Item | content | resources/views/admin/blocks/types/feature-item.blade.php | title, content via les lignes de traduction de texte | url canonique partagée | Relation avec le feature-grid parent | N'est pas un conteneur | resources/views/pages/partials/blocks/feature-item.blade.php | Délègue à la présentation en cartes de Column Item | transitional | PublicHeroBlockRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Feature Item est désormais un contrat enfant de soutien publié pour Feature Grid, qui continue de partager la coque en carte existante de Column Item. |
Layout
| Slug | Libellé | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglage | Champs média/relation | Comportement enfants/conteneur | Source du moteur de rendu public | Contrat de racine du moteur de rendu | Statut actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| section | Section | layout | resources/views/admin/blocks/types/section.blade.php | Aucun | settings.layout_name; settings.spacing | Blocs enfants uniquement | Conteneur ; pas de liste blanche explicite des enfants | resources/views/pages/partials/blocks/section.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PublicLayoutStructureTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | La phase 3 conserve Section uniquement comme layout : les réglages de layout partagés restent canoniques, il possède la racine sémantique et il ne déplace pas le texte visible par l'utilisateur dans des réglages arbitraires. |
| container | Container | layout | resources/views/admin/blocks/types/container.blade.php | Aucun | settings.layout_name; settings.width; settings.flow | Blocs enfants uniquement | Conteneur ; pas de liste blanche explicite des enfants | resources/views/pages/partials/blocks/container.blade.php | Possède son conteneur racine | clear | PublicEditorialBlocksRenderingTest, PublicLayoutStructureTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | La valeur par défaut héritée retombe toujours sur le flux empilé lorsqu'elle n'est pas définie, tandis que Flow: None explicite reste la voie de composition neutre vis-à-vis du layout. |
| cluster | Cluster | layout | resources/views/admin/blocks/types/cluster.blade.php | Aucun | settings.layout_name; settings.gap; settings.alignment; settings.items_alignment; settings.wrap; settings.width | Blocs enfants uniquement | Conteneur ; pas de liste blanche explicite des enfants | resources/views/pages/partials/blocks/cluster.blade.php | Possède son de cluster racine | clear | PublicEditorialBlocksRenderingTest, PublicLayoutStructureTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Les réglages de layout partagés restent explicites et détenus par le moteur de rendu, y compris la voie de composition existante compatible navbar (full-width, between, center, nowrap), sans ajouter de logique spécifique à la navbar. |
| grid | Grid | layout | resources/views/admin/blocks/types/grid.blade.php | Aucun | settings.layout_name; settings.columns; settings.gap | Blocs enfants uniquement | Conteneur ; pas de liste blanche explicite des enfants | resources/views/pages/partials/blocks/grid.blade.php | Possède son de grille racine | clear | PublicEditorialBlocksRenderingTest, PublicLayoutStructureTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest | Les réglages de grille partagés restent canoniques et la sortie publique reste limitée aux correspondances de classes wb-grid- livrées et wb-gap- prises en charge. |
Motif
| Slug | Libellé | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglage | Champs média/relation | Comportement enfants/conteneur | Source du moteur de rendu public | Contrat de racine du moteur de rendu | Statut actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| content_header | Content Header | pattern | resources/views/admin/blocks/types/content_header.blade.php | title, subtitle, meta via des lignes de traduction de texte | settings.alignment | meta est stocké comme contenu de liste structurée | Pas un conteneur | resources/views/pages/partials/blocks/content_header.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTypePhaseThreeContractsTest, BlockTranslationIntegrityTest | Content Header est un bloc de motif de type content-shell. Il conserve le titre, l'introduction et le texte meta gérés par langue (locale), rend toujours son titre en H1, ignore au moment du rendu toute valeur de niveau de titre héritée enregistrée, et ne garde en partage que l'alignement. |
| alert | Alert | pattern | resources/views/admin/blocks/types/alert.blade.php | title, content via des lignes de traduction de texte | settings.variant | Aucun | Pas un conteneur | resources/views/pages/partials/blocks/alert.blade.php | Possède la racine de son alerte | clear | PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | La variante partagée et le texte traduit s'alignent proprement. |
Navigation
| Slug | Libellé | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglage | Champs média/relation | Comportement enfants/conteneur | Source du moteur de rendu public | Contrat de racine du moteur de rendu | Statut actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| link-list | Link List | navigation | resources/views/admin/blocks/types/link-list.blade.php | title, subtitle, content via des lignes de traduction de texte | Aucun | Blocs link-list-item enfants | Conteneur ; uniquement des enfants link-list-item | resources/views/pages/partials/blocks/link-list.blade.php | Possède sa racine .wb-link-list lorsque des lignes enfants existent | clear | LinkListBlockTest, PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest, BlockTypePhaseThreeContractsTest | La phase 3 rend désormais le texte d'introduction traduit existant au-dessus de la liste de liens publique, sans modifier le comportement des éléments enfants. |
| link-list-item | Link List Item | navigation | resources/views/admin/blocks/types/link-list-item.blade.php | title obligatoire, subtitle facultatif et content facultatif, via des lignes de traduction de texte | url partagé obligatoire | Relation avec le link-list parent | Pas un conteneur | resources/views/pages/partials/blocks/link-list-item.blade.php | Possède la racine du lien de la ligne et omet l'élément de description lorsque le contenu est vide | clear | LinkListBlockTest, PageBuilderExperienceTest, PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | L'URL partagée associée au texte de ligne traduit est cohérente. |
| toc | TOC | navigation | resources/views/admin/blocks/types/toc.blade.php | Aucun | Uniquement le title canonique | Blocs header publiés de la même page avec des ancres valides | Pas un conteneur ; les anciennes lignes enfants sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/toc.blade.php | Possède son wrapper TOC généré lorsque des titres existent | clear | PublicRichContentTest, PageBuilderExperienceTest | La phase 3 conserve TOC centré uniquement sur les titres de page détectés et ne traite plus les blocs enfants arbitraires comme du contenu public de TOC. |
| breadcrumb | Breadcrumb | navigation | resources/views/admin/blocks/types/breadcrumb.blade.php | Aucun | settings.home_label ; settings.include_current partagés | Contexte de fil d'Ariane de la page, du site et de la langue (locale) courants | Pas un conteneur | resources/views/pages/partials/blocks/breadcrumb.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest | La phase 3 préserve les réglages de fil d'Ariane exposés via le chemin partagé BlockRequest, de sorte que le comportement du formulaire correspond désormais à la persistance et au rendu. |
| header-actions | Header Actions | navigation | resources/views/admin/blocks/types/header-actions.blade.php | Aucun | settings.show_mode_toggle ; settings.show_accent_toggle ; settings.show_search partagés | Route de recherche et hooks d'interface côté client | Pas un conteneur | resources/views/pages/partials/blocks/header-actions.blade.php | Possède uniquement son cluster d'actions interne | clear | PublicEditorialBlocksRenderingTest | Bloc utilitaire système ; par conception, il ne détient aucune traduction. |
| sticky-navbar | Navbar | navigation | resources/views/admin/blocks/types/sticky-navbar.blade.php | Aucun | settings.layout_name; settings.sticky_mode | Blocs enfants imbriqués de la navbar | Conteneur ; les enfants autorisés sont container, cluster, header, plain_text, rich-text, button_link, navbar-brand, navbar-navigation, header-actions, search-form | resources/views/pages/partials/blocks/sticky-navbar.blade.php | Le moteur de rendu public possède la racine externe | clear | PublicEditorialBlocksRenderingTest, PublicLayoutStructureTest, BlockTypePhaseThreeContractsTest | La phase 3 aligne le slug persisté sticky-navbar sur Block::ownsPublicRoot(), de sorte que Navbar ne reçoit plus de wrapper de bloc public générique supplémentaire. |
| navbar-brand | Navbar Brand | navigation | resources/views/admin/blocks/types/navbar-brand.blade.php | title, subtitle via des lignes de traduction de texte | settings.url ; settings.target ; settings.aria_label partagés | Média du logo partagé via media_id ; repli sur l'URL d'accueil du site | Pas un conteneur | resources/views/pages/partials/blocks/navbar-brand.blade.php | Possède uniquement le lien de marque interne | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTranslationIntegrityTest, BlockTypePhaseThreeContractsTest | La phase 3 aligne le comportement d'enregistrement de l'administration sur le contrat du moteur de rendu livré : l'URL enregistrée explicite l'emporte, sinon le chemin d'accueil du site courant est utilisé lorsqu'il est disponible, puis / en dernier repli sûr. |
| navbar-navigation | Navbar Navigation | navigation | resources/views/admin/blocks/types/navbar-navigation.blade.php | Aucun | Le title canonique comme libellé ARIA partagé ; settings.menu_key | Arbre de menu NavigationItem partagé | Pas un conteneur | resources/views/pages/partials/blocks/navbar-navigation.blade.php | Possède uniquement le wrapper de navigation interne | clear | PublicEditorialBlocksRenderingTest | La liaison de menu partagée et le libellé ARIA relèvent du comportement actuel détenu par le produit. |
| sidebar-brand | Sidebar Brand | navigation | resources/views/admin/blocks/types/sidebar-brand.blade.php | title, subtitle via des lignes de traduction de texte | settings.url ; settings.target ; settings.aria_label partagés | Média du logo partagé via media_id ; repli sur l'URL d'accueil du site | Pas un conteneur | resources/views/pages/partials/blocks/sidebar-brand.blade.php | Possède uniquement le lien de marque interne | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTranslationIntegrityTest, BlockTypePhaseThreeContractsTest | La phase 3 donne à Sidebar Brand le même ordre de repli du nom accessible en cas de logo seul que Navbar Brand, ainsi que le même contrat de repli prudent pour l'URL partagée. |
| sidebar-navigation | Sidebar Navigation | navigation | resources/views/admin/blocks/types/sidebar-navigation.blade.php | title via des lignes de traduction de texte | settings.menu_key ; settings.layout_name ; settings.show_icons ; settings.active_matching partagés | Soit l'arbre NavigationItem du CMS, soit des blocs enfants manuels | Conteneur ; uniquement des enfants sidebar-nav-item et sidebar-nav-group | resources/views/pages/partials/blocks/sidebar-navigation.blade.php | Possède sa racine | clear | PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | Les réglages partagés du mode menu et le mode enfants manuels sont tous deux explicites. |
| sidebar-nav-item | Sidebar Nav Item | navigation | resources/views/admin/blocks/types/sidebar-nav-item.blade.php | title via des lignes de traduction de texte | settings.url ; settings.target ; settings.icon ; settings.active_mode ; settings.manual_active partagés | Slug partagé du catalogue d'icônes ; relation avec la barre latérale parente | Pas un conteneur | resources/views/pages/partials/blocks/sidebar-nav-item.blade.php | Possède la racine de son lien de barre latérale | clear | PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | Le comportement de lien partagé et le libellé traduit s'accordent bien. |
| sidebar-nav-group | Sidebar Nav Group | navigation | resources/views/admin/blocks/types/sidebar-nav-group.blade.php | title via des lignes de traduction de texte | settings.icon ; settings.initially_open ; settings.layout_name partagés | Blocs sidebar-nav-item enfants ; slug du catalogue d'icônes | Conteneur ; uniquement des enfants sidebar-nav-item | resources/views/pages/partials/blocks/sidebar-nav-group.blade.php | Possède sa racine .wb-nav-group | clear | PublicEditorialBlocksRenderingTest, PageBuilderExperienceTest, BlockTranslationIntegrityTest, BlockTypePhaseThreeContractsTest | La phase 3 conserve le contrat du wrapper nav-group livré de WebBlocks UI, tandis que les liens enfants manuels imbriqués réutilisent désormais la même sémantique d'élément de barre latérale pour href, target, icône et sortie de l'état actif. |
| search-form | Search Form | navigation | resources/views/admin/blocks/types/search-form.blade.php | title, subtitle, content via des lignes de traduction de texte | variant ; settings.show_button partagés | Contexte de la route de recherche, du site et de la langue (locale) | Pas un conteneur | resources/views/pages/partials/blocks/search-form.blade.php | Possède sa racine | clear | SearchFormTest, PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | Les réglages partagés d'affichage du bouton et les libellés traduits sont explicites. |
| sidebar-footer | Sidebar Footer | navigation | resources/views/admin/blocks/types/sidebar-footer.blade.php | title, subtitle, content via des lignes de traduction de texte | settings.variant partagé | Aucun | Pas un conteneur | resources/views/pages/partials/blocks/sidebar-footer.blade.php | Possède la racine de son bloc de pied de page interne | clear | PublicEditorialBlocksRenderingTest, BlockTranslationIntegrityTest | La variante partagée avec du texte traduit est simple. |
Formulaires
| Slug | Libellé | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglage | Champs média/relation | Comportement enfants/conteneur | Source du moteur de rendu public | Contrat de racine du moteur de rendu | Statut actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| contact_form | Contact Form | form | resources/views/admin/blocks/types/contact_form.blade.php | title, content, submit_label, success_message via des lignes de traduction du formulaire de contact | settings.recipient_email ; settings.send_email_notification ; settings.store_submissions partagés | Les envois contact_messages sont rattachés au bloc et à la page | Pas un conteneur | resources/views/pages/partials/blocks/contact_form.blade.php | Possède sa racine section.wb-card et émet un formulaire natif protégé par CSRF qui poste vers /contact-messages | clear | ContactFormModuleTest, InternalContentApiTest, ContactMailDiagnoseCommandTest | Le moteur de rendu émet un champ de contrôle anti-spam masqué et généré, détenu par le CMS, qui n'est pas une saisie normale du visiteur et ne doit pas être créé manuellement. Les envois dont le champ de contrôle est rempli renvoient un succès générique, sans enregistrement ni notification. Les messages légitimes sont enregistrés avant la notification, les messages notés comme spam sont conservés pour relecture par l'administration, l'ordre de repli du destinataire est le bloc, le site, CONTACT_RECIPIENT_EMAIL, puis MAIL_FROM_ADDRESS, et les pages de contact ne doivent pas utiliser Trusted HTML, des formulaires bruts ou mailto: comme substituts. |
Avancé
| Slug | Libellé | Catégorie | Source du formulaire d'administration | Champs traduisibles | Champs partagés/de réglage | Champs média/relation | Comportement enfants/conteneur | Source du moteur de rendu public | Contrat de racine du moteur de rendu | Statut actuel | Tests / couverture | Lacunes connues / notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| html | HTML (Trusted) | advanced | resources/views/admin/blocks/types/html.blade.php | Aucun | Le content HTML de confiance canonique | Les registres publics d'overlay et de fin de body peuvent recevoir des fragments extraits | Pas un conteneur ; les anciennes lignes enfants sont conservées, mais l'ajout de nouveaux enfants n'est pas pris en charge | resources/views/pages/partials/blocks/html.blade.php | Possède un d'enveloppe autour du balisage de confiance et peut aussi émettre du contenu d'overlay ou de fin de body hors bande | mostly clear | PublicEditorialBlocksRenderingTest, PublicRichContentTest, PageBuilderExperienceTest | La phase 3 cesse de traiter Trusted HTML comme un wrapper conteneur d'enfants public. Le balisage de confiance peut toujours affecter la sortie partagée d'overlay ou de fin de body au-delà de la racine visible. |
Vue d'ensemble de la validation et de la persistance
Aujourd'hui, les types de bloc publiés ne disposent pas chacun de leur propre classe request dédiée.
App\Http\Requests\Admin\BlockRequestest le chemin de requête d'édition partagé- les branches spécifiques à chaque slug dans cette requête normalisent les champs vers le stockage canonique actuel
App\Support\Blocks\BlockPayloadWriterpersiste la charge utile normalisée du blocApp\Support\Blocks\BlockTranslationWriterdéplace les champs appartenant à la langue (locale) vers les lignes de traduction des familles enregistréesApp\Support\Blocks\BlockTranslationResolverrésout les valeurs traduites ou de repli sur une instance de bloc affichable
Ce chemin de requête partagé est l'une des raisons pour lesquelles la Phase 1 documente d'abord les contrats, avant tout travail d'édition piloté par schéma.
Lacunes et backlog
Lacunes importantes encore présentes après les correctifs actuels de la Phase 3 :
galleryconserve encore un chemin d'éléments de repli hérité, basé sur les réglages, lorsque les lignes canoniques ordonnées deblock_mediasont absentestable— son moteur de rendu prend encore en charge un chemin de repli hérité basé sursettings.rowsmême si le formulaire d'administration principal écrit le texte traduit des lignesheroconserve encore des replis de champs hérités lorsque les champs d'introduction traduits canoniques sont videsfeature-gridetfeature-itemsont désormais publiés car ils s'appuient sur le code source, mais ils restent volontairement des contrats délégués transitoires au-dessus des chemins de présentation partagés Columns ou Column Itemtabs,slider,menuetfaq-listexistent encore comme lignes héritées du catalogue à l'état de brouillon, avec des formulaires ou moteurs de rendu de compatibilité, mais ce ne sont pas des contrats publiés du cœur et ils doivent continuer à échouer de façon sûre dans la fenêtre modale de contrat et dans la sortie d'auditshowcase-listetcontact-infon'existent que comme chemins de compatibilité pour le rendu public, et non comme blocs publiés du catalogue du cœur ; leurs liens issus des réglages suivent désormais les mêmes règles d'URL publique sûre que les autres moteurs de rendu de blocs- les catalogues publiés et les catalogues en brouillon coexistent : toute exposition future dans l'administration doit donc distinguer explicitement les contrats publiés du cœur des lignes en brouillon ou spécifiques à l'installation
Phase 3 recommandée
Travail de standardisation recommandé ultérieurement pour les groupes de blocs :
- définir des groupes de blocs stables appartenant au produit, comme layout, contenu, navigation, motif et avancé, dans une source de vérité unique
- aligner les regroupements du sélecteur, ceux de la documentation et ceux de l'administration Block Types sur cette même source
- décider quels blocs actuellement en brouillon ou transitoires doivent devenir pris en charge, archivés ou explicitement hérités
- standardiser quels contrats reposent sur des traductions et lesquels sont volontairement partagés uniquement, avant de commencer tout travail de formulaire piloté par schéma
Résumé de la Phase 1
La Phase 1 établit l'inventaire actuel des contrats publiés sans modifier le comportement d'édition des blocs, leur stockage ni le rendu public.
C'était le point d'arrêt prévu pour la livraison de la Phase 1.
Résumé de la Phase 2
La Phase 2 rend le contrat documenté visible dans l'administration Block Types sous forme d'information en lecture seule, tout en laissant inchangés le comportement d'édition des blocs, le stockage, les moteurs de rendu et le sélecteur.
Résumé de la Phase 3
La Phase 3 commence à résoudre les lacunes documentées à faible risque des contrats sans ajouter d'éditeur de schéma, de générateur de formulaires dynamique ni de système de formulaires de blocs piloté par la base de données.
codesuit désormais le chemin de traduction de texte existant pour le titre, le libellé et le corps de l'extrait, tout en gardant le langage de syntaxe partagétablesuit désormais le chemin de traduction de texte existant pour le titre et le texte des lignes, tout en gardant le style de tableau partagébreadcrumbconserve désormais les réglages partagés exposés lors de l'enregistrementstat-cardutilise désormais l'URL facultative existante dans le moteur de rendu public via un lien simple et sûrlink-listaffiche désormais le texte d'introduction traduit existant au-dessus de la liste des éléments enfantssticky-navbaraligne désormais la propriété persistée de la racine de la Navbar surBlock::ownsPublicRoot()afin que le shell public n'ajoute pas d'enveloppe générique supplémentaireimagesuit désormais le chemin de traduction d'images existant pour la légende et le texte alternatif, tout en gardant partagés le média sélectionné et l'URL de lien facultativegalleryutilise désormais la table dépendante de la langue (locale)block_gallery_item_translationspour le texte alternatif, la légende, le titre de superposition et le texte de superposition de chaque élément, tout en gardant partagés les médias ordonnés de la galerie et les réglages de présentation, en conservant les éléments de repli hérités pour les anciens contenus et en excluant le titre et la description hérités de la galerie de l'édition normale et de la sortie publiquedownloadsuit désormais le chemin de traduction de texte existant pour le libellé visible et le texte d'aide, tout en gardant partagés le média sélectionné et la variante de boutonfile,videoetaudiodisposent désormais de formulaires d'administration à part entière et d'une normalisation des requêtes, de sorte que le texte visible traduit et les médias partagés ou les sources d'URL font l'aller-retour par le même contrat que celui utilisé pour leur rendu publicimage,gallery,download,file,videoetaudion'acceptent plus le placement arbitraire de nouveaux enfants et n'affichent plus publiquement d'arbres d'enfants historiques arbitraires, tandis que les lignes enfants existantes restent conservées dans les arbres de blocs de l'administrationcode,table,quote,tocethtmln'acceptent plus le placement normal de nouveaux enfants et n'affichent plus publiquement d'arbres d'enfants historiques arbitraires, tandis que les lignes enfants existantes restent conservées dans les arbres de blocs de l'administrationnavbar-brandetsidebar-brandpartagent désormais un contrat de repli prudent basé sur l'URL enregistrée ou la page d'accueil du site, et tous deux conservent un nommage accessible et sûr pour une sortie limitée au logo, sans imposer de texte visiblesidebar-nav-groupréutilise désormais la même sémantique de sortie des éléments manuels de la barre latérale quesidebar-nav-itempour les liens enfants imbriqués, tout en conservant le contrat existant de l'enveloppe nav-group de WebBlocks UIsection,container,grid,cluster,cardetcontent_headerutilisent désormais la même source de contrat livrée dans le registre, la fenêtre modale de contrat en lecture seule de l'administration, la sortie d'audit, la documentation et la couverture de régression cibléehero,columns,column_item,cta,feature-gridetfeature-itemsont désormais publiés dans le catalogue du cœur livré, documentés dans le registre de contrats partagé et couverts comme contrats marketing ou de contenu structuré adossés au code source, au lieu de rester à l'état de brouillon ou sous-documentés- les modifications propres à une seule langue (locale) pour les boutons CTA gérés et les éléments enfants structurés conservent désormais les URL partagées tout en mettant à jour les libellés ou textes traduits
- les primitives de layout conservent les réglages de layout partagés et la structure des enfants dans le stockage canonique des blocs, plutôt que dans des lignes de traduction ou des champs de texte arbitraires
cardutilise désormais un contrat de shell composable : la Card parente possède la racinewb-card, les régions de Card possèdentwb-card-header,wb-card-bodyetwb-card-footer, les blocs de région ne sont valides que sous Card, et le texte Card enregistré hérité n'est conservé que via un chemin de rendu de repli minimal sans régioncontent_headerconserve le titre, l'introduction et le texte meta traduits, affiche toujours son titre en H1, ignore de manière sûre les valeurs de niveau de titre héritées enregistrées et conserve sa racine sémantique<header class="wb-content-header">sous la responsabilité du moteur de rendu, sans enveloppe génériquetestimonialetstatsrestent documentés honnêtement comme un comportement de simple alias qui délègue aux chemins de rendu existants Quote ou Columns, plutôt que comme des contrats publiés du cœur autonomestabs,slider,menuetfaq-listrestent des slugs en brouillon ou de compatibilité de l'époque des alias, et non des contrats publiés du cœur, tandis queshowcase-listetcontact-inforestent des moteurs de rendu de compatibilité uniquement publics, sans entrée de contrat dans le catalogue du cœur livré