Skip to Content

Page Builder

Le Page Builder permet de construire des contenus structurés à base de blocs réordonnables, traduisibles et configurables. Chaque type de bloc a son propre rendu et ses propres options.

Utilisation dans le cockpit

Lorsqu’une ressource utilise le Page Builder, l’édition du contenu se fait via une interface dédiée :

  • Ajouter un bloc : cliquez sur le bouton + pour insérer un nouveau bloc à l’endroit voulu.
  • Réorganiser : faites glisser un bloc pour modifier sa position.
  • Configurer : l’icône engrenage de chaque bloc ouvre ses paramètres (niveau de titre, format vidéo, colonnes, etc.).
  • Supprimer : la corbeille retire définitivement le bloc et ses médias associés.
  • Multi-langue : la structure des blocs est partagée entre toutes les langues, mais le contenu (textes, images) est édité indépendamment par langue.

Blocs disponibles

Contenu texte

BlocDescription
paragraphParagraphe avec éditeur de texte riche (Redactor)
headingTitre avec sélecteur de niveau (H1 à H4)
quoteCitation avec attribution
codeBloc de code avec coloration syntaxique (HTML, CSS, JavaScript, PHP, JSON, Bash)
listListe ordonnée ou non ordonnée

Médias

BlocDescription
imageImage unique avec texte alternatif et légende
galleryGalerie d’images en grille
coverImage de couverture plein écran avec titre et sous-titre en overlay
videoEmbed YouTube ou Vimeo via URL, avec preview live
mapCarte Google Maps ou OpenStreetMap par adresse

Mise en page

BlocDescription
separatorLigne de séparation horizontale (marge et style configurables)

Blocs avancés

BlocDescription
authorAffiche les informations d’un auteur depuis un modèle Eloquent
logo-cloudGrille de logos avec liens optionnels
formFormulaire dynamique avec validation, envoi d’email et historique des soumissions

Configuration de la ressource

L’ajout du Page Builder à une ressource se fait via le champ PageBuilder :

use Lochness\Fields\PageBuilder; public function fields(): array { return [ PageBuilder::make('Contenu', 'block_builder') ->translated() ->blocks([ 'paragraph', 'heading', 'image', 'gallery', 'video', 'quote', 'form', ]), ]; }

La colonne en base doit être de type longText ou json :

$table->longText('block_builder')->nullable();

Méthodes disponibles

MéthodeDescription
->blocks([...])Liste des types de blocs autorisés
->translated()Active le support multi-langue
->configure('type', [...])Configure un bloc spécifique (toolbar Redactor, modèle Eloquent, etc.)
->preformatted([...])Enregistre des blocs personnalisés (voir ci-dessous)

Exemples de configuration

PageBuilder::make('Contenu', 'block_builder') ->blocks(['paragraph', 'author']) ->configure('paragraph', [ 'toolbar' => ['bold', 'italic', 'link'], ]) ->configure('author', [ 'model' => \App\Models\Author::class, 'display' => 'full_name', 'order_by' => 'first_name', ])

Bloc Formulaire

Le bloc form permet de créer des formulaires dynamiques sans écrire de code. Il prend en charge :

  • Les types de champs : text, email, textarea, radio, checkbox
  • La validation côté serveur
  • Le layout en colonnes (demi ou pleine largeur)
  • L’envoi d’un email au destinataire configuré, avec copie optionnelle au visiteur
  • L’historique des soumissions consultable dans /cockpit/forms
  • La protection anti-spam : honeypot + rate limiting (5 requêtes/min/IP)
  • Le reCAPTCHA v3 (optionnel)

Configuration reCAPTCHA

Dans le fichier .env :

RECAPTCHA_SITE_KEY=your_site_key RECAPTCHA_SECRET_KEY=your_secret_key

Dans config/services.php :

'recaptcha' => [ 'site_key' => env('RECAPTCHA_SITE_KEY'), 'secret_key' => env('RECAPTCHA_SECRET_KEY'), ],

Configuration Google Maps

Pour utiliser l’API Embed officielle dans le bloc map, ajoutez dans .env :

GOOGLE_MAPS_KEY=your_key

Et dans config/services.php :

'google_maps' => ['key' => env('GOOGLE_MAPS_KEY')],

Sans clé, un fallback OpenStreetMap est utilisé automatiquement.

Rendu frontend

L’affichage des blocs sur le site se fait avec la directive Blade @blocks :

@blocks($model, 'block_builder', app()->getLocale(), 'actualites.modules')
ParamètreDescription
$modelInstance du modèle Eloquent
'block_builder'Nom de l’attribut Page Builder
localeCode langue (optionnel, défaut : locale courante)
viewPathPréfixe de vue pour personnaliser le rendu (optionnel)

Résolution des vues

Le renderer cherche les vues dans cet ordre :

  1. Vue personnalisée du projet : {viewPath}.{type} (ex : actualites.modules.heading)
  2. Vue d’un bloc preformatted : la valeur retournée par frontView()
  3. Vue par défaut du package : lochness::front.page-builder.blocks.{type}

Variables disponibles dans les vues

VariableDescription
$blockStructure complète du bloc
$contentContenu traduit du bloc
$dataDonnées statiques (structure.data)
$blockSettingsSettings du bloc (_settings)
$mediaMédia associé (Spatie Media Library) ou null
$modelInstance du modèle parent
$localeCode langue actuel
$blockIdIdentifiant unique du bloc
$typeType du bloc
$attributeNom de l’attribut Page Builder

Utilisez $blockSettings et non $settings. La variable $settings peut être écrasée par un View::composer('*').

Exemple de vue personnalisée

{{-- resources/views/actualites/modules/heading.blade.php --}} @php $level = $blockSettings['level'] ?? 2; @endphp <h{{ $level }} class="font-bold text-2xl"> {{ $content['text'] ?? '' }} </h{{ $level }}>

Blocs personnalisés (preformatted)

Pour créer un type de bloc spécifique au projet, étendez AbstractPreformattedBlock :

namespace App\Modules\Preformatted; use Lochness\Fields\PageBuilder\AbstractPreformattedBlock; class TestimonialBlock extends AbstractPreformattedBlock { public static function type(): string { return 'testimonial'; } public static function name(): string { return 'Témoignage'; } public function fields(): array { return [ ['name' => 'title', 'type' => 'heading', 'label' => 'Titre', 'levels' => [2, 3]], ['name' => 'description', 'type' => 'richtext', 'label' => 'Description'], ]; } public function repeatable(): array { return [ ['name' => 'name', 'type' => 'text', 'label' => 'Nom', 'required' => true], ['name' => 'quote', 'type' => 'richtext', 'label' => 'Témoignage', 'required' => true], ]; } public function frontView(): string { return 'modules.preformatted.testimonial.front'; } }

Puis enregistrez la classe dans la ressource :

PageBuilder::make('Contenu', 'block_builder') ->blocks(['paragraph', 'heading']) ->preformatted([ \App\Modules\Preformatted\TestimonialBlock::class, ])

Types de champs supportés

TypeDescription
textChamp texte
textareaZone de texte multi-lignes
headingTexte avec sélecteur de niveau H1-H4
richtextÉditeur Redactor complet

Méthodes de l’interface

MéthodeRôle
type()Identifiant unique du bloc
name()Nom affiché dans l’éditeur
icon()Icône SVG (taille size-5)
fields()Champs principaux (traduits)
settings()Paramètres du bloc (non traduits)
repeatable()Items répétables
hasImage()Activation et configuration de l’image
frontView()Vue Blade pour le rendu frontend
editorView()Vue éditeur personnalisée (optionnel)

Structure des données

Le Page Builder stocke ses données en JSON dans un seul champ. La structure (ordre, types, settings) est partagée entre toutes les langues, le contenu est indexé par locale :

{ "structure": [ { "id": "blk_abc12345", "type": "heading", "position": 0, "data": { "_settings": { "level": "2" } } } ], "content": { "fr": { "blk_abc12345": { "text": "Mon titre" } }, "en": { "blk_abc12345": { "text": "My title" } } } }

Gestion des médias

Les images sont stockées via Spatie Media Library, dans des collections nommées :

pagebuilder_{attribute}_{blockId}_{locale}

Pour les blocs avec images par item (par exemple logo-cloud) :

pagebuilder_{attribute}_{blockId}_{itemId}_{locale}

Quand un bloc est supprimé, toutes ses collections media (fichiers + entrées en base) sont supprimées automatiquement.

Last updated on