Page Builder Internals

A GrapesJS-based visual editor extended with TruCMS blocks, live shortcodes, a template library, data-bound sections and an optional AI assistant. This page explains the pieces; the how-to guides are in the Extend section.

In the user guide: Page Builder, Template Library in the Builder, Dynamic Blocks & Shortcodes and Data-Bound Sections.

How the editor is assembled

/admin/pages/{page}/edit-content?locale=en
  PageController@editContent  -> view page-builder.editor
     |-- loads the saved content + styles of ONE locale into #tru-page-builder
     |-- window.PageBuilderSettings   (page url, widget areas, AI config)
     |-- grapesjs.init({ plugins: [webpage preset, image editor, style-bg, TruCMS plugin, html-code, AI agent] })
     |      pluginsOpts[TruCMS plugin]:
     |          templateLibrary  -> admin.page-builder.load / categories  (JSON)
     |          shortcodes       -> ShortcodeRegistry::all()          (embedded JSON)
     |          shortcodeCategories, shortcodesApi, bakeApi
     |          boundSources     -> BindingSourceRegistry::editorPayload()
     |-- canvas styles: editor.scss + Google Fonts + compiled theme CSS (so the canvas shows real colours)
  Save (AJAX) -> PageController@updateContent -> clean_page_builder(content) -> page_translations.content/styles

The editor code is in resources/themes/admin/assets/js/grapesjs/:

FileRole
index.jsThe TruCMS GrapesJS plugin: default blocks, labels, categories, loads the modules below
components.js, traits.js, styles.jsBootstrap-aware components, trait panels and style manager sections
dynamic-shortcodes.jsTurns each server-side shortcode definition into a GrapesJS component type with traits and a live preview
shortcode-base.jsRegistration helper for shortcode components (x-shortcode-{id} tag, preview URL, traits)
block-categories.jsBlock panel categories and their priority scale
template-library.jsThe template-library lightbox (search, categories, kind filter, insert, preview)
bound-sections.jsData-bound sections: pick records, bake markers, re-bake on change
section-divider.js, animations.js, rellax-traits.jsShape dividers, entrance animations and parallax traits
ai-agent.jsThe in-editor AI assistant

Blocks, shortcodes and live components

A shortcode in TruCMS is a Blade component tag named <x-shortcode-{id}>, written into the saved HTML with its configuration as attributes. At save time nothing is expanded; at render time PageSlugRenderer runs Blade::render() over the content, so the component executes with fresh data.

  1. Definition (PHP)A class implementing ShortcodeContract returns a ShortcodeDefinition: id, display name, tag, category, icon, default attributes, traits (the editor's form fields), assets and AI metadata.
  2. RegistrationShortcode::registerIfMissing(MyShortcode::class) in a provider's boot(); categories are registered with Shortcode::category().
  3. EditorThe editor receives all definitions as JSON, creates a block and component type for each, and renders a live preview by calling admin.page-builder.shortcodes.preview (or render-shortcode) with the current attributes.
  4. Front endThe Blade component class resolves its attributes into data and renders a theme view. Assets declared in the definition (Vite entries, styles, scripts) are loaded only on pages whose content contains the tag.

Core shortcodes (app/Shortcodes): blog, blog-cards, adslot, contact, social-share and widget-area. Booking and TruCommerce register many more (see the catalogue). To build your own, follow Shortcodes.

Template library

The editor's Templates panel lists rows from the page_templates table (App\Models\PageTemplate): kind = section or page, category, thumbnail, html, is_premium, is_new. The listing endpoint never returns HTML (so locked premium markup cannot leak); Insert calls admin.page-builder.templates.show, which renders the template's Blade components, returns the HTML, the template CSS and the module assets it needs. Premium templates return HTTP 403 without the extended licence.

Data-bound sections

A section can display real records (products, posts, services…) while remaining a normal editable section. The wrapper carries data-bound="source" and the editor writes data-bound-ids; elements inside carry data-bind* markers. When the author changes the selection the editor calls admin.page-builder.shortcodes.bake, which fills the markers with current data and returns HTML that still contains the markers. A hourly job (pages:refresh-bound) plus model observers re-bake saved pages when the underlying records change. Full details: Data-bound sections.

Page-level settings

The page form (resources/themes/admin/components/pages-form.blade.php) stores a settings JSON object. Header options such as floating/sticky/dark/shadow/width and menu choices reach the header as request-scoped theme options through override_theme_options(). A page that pins primary_menu therefore ignores later changes to the site's primary menu — test menu work on a page without that setting.

AI assistant

When the page_builder_ai_enabled setting is on, a provider is fully configured and the user holds edit page, the editor adds a chat panel. (The settings keys and the ProviderModelSelect / EncryptedPassword field types exist, but no core settings section currently registers an admin screen for them — see AI assistant integration.) Requests post to admin.page-builder.ai.generate (throttle page-builder-ai, default 20/minute). PageBuilderAiManager builds a prompt containing a capability catalogue of every registered shortcode, so a plugin shortcode is AI-usable by default; a definition opts out with ->ai(['enabled' => false]). Providers are OpenAI, Anthropic, Gemini, Azure OpenAI and any OpenAI-compatible endpoint; credentials are stored encrypted. See AI assistant integration.

Security notes for builder content