layr / builder
Layr page builder package for TypiCMS pages
Requires
- php: ^8.4
- typicms/core: ^17.0
Requires (Dev)
- mike-bronner/laravel-model-caching: ^13.1
- orchestra/testbench: ^11.0
- phpunit/phpunit: ^12.5
- typicms/nestablecollection: ^6.0
- typicms/translatable: ^2.0
- dev-main / 0.3.x-dev
- v0.3.0
- v0.2.0-rc.38
- v0.2.0-rc.37
- v0.2.0-rc.36
- v0.2.0-rc.35
- v0.2.0-rc.34
- v0.2.0-rc.33
- v0.2.0-rc.32
- v0.2.0-rc.31
- v0.2.0-rc.30
- v0.2.0-rc.29
- v0.2.0-rc.28
- v0.2.0-rc.27
- v0.2.0-rc.26
- v0.2.0-rc.25
- v0.2.0-rc.24
- v0.2.0-rc.23
- v0.2.0-rc.22
- v0.2.0-rc.21
- v0.2.0-rc.20
- v0.2.0-rc.19
- v0.2.0-rc.18
- v0.2.0-rc.17
- v0.2.0-rc.16
- v0.2.0-rc.15
- v0.2.0-rc.14
- v0.2.0-rc.13
- v0.2.0-rc.12
- v0.2.0-rc.11
- v0.2.0-rc.10
- v0.2.0-rc.9
- v0.2.0-rc.8
- v0.2.0-rc.7
- v0.2.0-rc.6
- v0.2.0-rc.5
- v0.2.0-rc.4
- v0.2.0-rc.3
- v0.2.0-rc.2
- v0.2.0-rc.1
- v0.1.1
- v0.1.0
- dev-codex/media-picker-typicms16
- dev-codex/media-picker
This package is auto-updated.
Last update: 2026-05-06 07:25:02 UTC
README
Layr is a reusable TypiCMS package that turns a TypiCMS page into a fully editable visual page, letting projects control the public look and layout of that page without baking host-specific code into the package.
What the package owns
- page builder UI inside the TypiCMS page form
- a configurable
layrpage template for public rendering - migrations for the builder payload fields on
pages - package-served built assets, so the host app does not need custom Vite entries
- configurable dynamic content sources for CMS-powered cards and carousels
Install
Preferred once the package is published to Packagist:
composer require layr/builder:^0.1
php artisan migrate
If you are installing from the GitLab repository before the first public release, use the VCS workflow below.
Install From GitLab Before Packagist
composer require layr/builder:dev-main
php artisan migrate
Compatibility:
- TypiCMS Core
17.0+ - PHP
8.4+
Optional:
php artisan vendor:publish --tag=layr-config
When upgrading an existing install, run php artisan migrate so the compiled public payload fields are added to pages.
Composer VCS example:
{
"repositories": [
{
"type": "vcs",
"url": "https://gitlab.com/blestonbandeira/layr.git"
}
],
"require": {
"layr/builder": "dev-main"
}
}
If you tag releases, prefer a version constraint such as ^0.1.
Once the package is public on Packagist, you can remove the custom repositories entry and require the tagged version directly.
After install:
- Open a page in TypiCMS admin.
- Set the page template to
Layr. - Build the page in the
Layrpanel. - Save the page.
Host app contract
This package is intended to be drop-in for a stock TypiCMS installation with the standard pages module views.
The package overrides the pages view namespace to provide a thinner page integration:
pages::admin.createpages::admin.editpages::public.layr
The admin wrappers delegate back to the original TypiCMS page form through the internal layr-pages-core namespace and then append the Layr builder panel.
If the host app already overrides pages::admin.create or pages::admin.edit, the app override will still win. In that case, include Layr using one of these partials:
layr::admin.page-form._integrated-formwhen you want the stock TypiCMS page form plus Layrlayr::admin.page-form._builder-panelwhen your host app already owns the surrounding page form markup
Layr keeps the editable builder HTML and CSS as authoring source, and compiles a sanitized public payload for frontend rendering. The builder should still only be exposed to trusted page editors, especially if you configure fixed sections that render host-defined Blade views.
Host Integration Examples
Host app owns the create or edit wrapper and wants the stock TypiCMS form plus Layr:
{!! BootForm::open()->put()->action(route('admin::update-page', $model->id))->addClass('main-content') !!}
{!! BootForm::bind($model) !!}
@include('layr::admin.page-form._integrated-form', ['model' => $model])
{!! BootForm::close() !!}
Host app already owns the surrounding form markup and only wants the Layr panel:
<div class="custom-page-editor">
@include('layr::admin.page-form._builder-panel', [
'model' => $model,
'wrapperClass' => 'mt-3',
])
</div>
Host app defines public page wrapper content around Layr:
'public_page' => [
'wrapper_class' => 'landing-shell',
'before_content_view' => 'site.pages.layr.before',
'after_content_view' => 'site.pages.layr.after',
],
Host app defines fixed sections without editing Layr internals:
'fixed_sections' => [
'templates' => [
'layr' => [
[
'key' => 'hero',
'label' => 'Hero',
'view' => 'site.pages.fixed.hero',
],
],
],
],
Architecture
Layr is intentionally split into package-owned services plus a TypiCMS adapter layer:
src/Support,src/Models,src/Contracts,config,database, andresourcescontain package behaviorsrc/TypiCmscontains the TypiCMS-specific integration points such as page-form requests, page rendering, and page import workflowsLayr\Contracts\LocaleContextcentralizes locale assumptions that would otherwise be hidden behind host helpers
There is a package-side architecture plan in docs/architecture-roadmap.md.
There is a follow-up execution plan for the remaining platform work in docs/ideal-state-execution-plan.md.
There is a visual redesign execution plan in docs/visual-redesign-execution-plan.md.
There is an editor-shell rebuild plan in docs/editor-v2-roadmap.md.
Visual release gate
Layr now ships with a lightweight visual regression gate for the redesign workstream.
Package-level checks:
npm run checknpm run check:previewnpm run check:visual-fixturesnpm run check:visual-canvasnpm run check:visual-dynamic
Public screenshot capture:
npm run capture:visual-fixtures:public
What each command covers:
check:preview: source and built iframe sizing safeguards for the builder canvascheck:visual-fixtures: baseline screenshot presence and minimum image dimensionscheck:visual-canvas: admin builder and device-frame geometry from the trusted baseline metadatacheck:visual-dynamic: public dynamic books grid and carousel structure, plus placeholder-copy leakscapture:visual-fixtures:public: regenerates the public visual fixtures intooutput/visual-fixtures/public-latest/
Current limitation:
- Public route automation is package-owned and repeatable today.
- Authenticated admin screenshot capture still requires a host session and remains a manual smoke test before a release candidate is tagged.
Recommended release flow for visual changes:
- Run the package checks above in Layr.
- Rebuild assets with
npm run build. - Regenerate public fixtures with
npm run capture:visual-fixtures:publicwhen the public rendering changed. - In the host app, smoke-test the authenticated builder: page load, drag/drop, keyboard insert, save, reload, and dark theme readability.
- Only tag a release candidate after both the automated checks and the host smoke test pass.
Admin dark-theme accent
Layr keeps the admin shell surfaces neutral and lets the host app override the dark-theme accent color.
Default package value:
'admin_theme' => [
'dark' => [
'accent' => '#8fb4ff',
],
],
Host override example:
'admin_theme' => [
'dark' => [
'accent' => '#6d28d9',
],
],
Layr derives the active text color and soft accent states from that one value, so hosts can match their brand without turning the builder into a full theme editor.
Dynamic content sources
Dynamic cards and dynamic carousels are driven by config/layr.php.
Example:
'dynamic_sources' => [
'books' => [
'label' => 'Books',
'permission' => 'read books',
'model' => \TypiCMS\Modules\Books\Models\Book::class,
'with' => ['image'],
'public_scope' => 'published',
'title_field' => 'title',
'subtitle_field' => 'summary',
'translated_title' => true,
'translated_subtitle' => true,
'image_relation' => 'image',
'image_attribute' => 'url',
'url_method' => 'url',
'edit_url_method' => 'editUrl',
'browse_route' => '{locale}::index-books',
'sort_column' => 'updated_at',
],
],
Fields:
label: source label shown in the editorpermission: optional additional admin permission for that source; Layr already requiresupdate pagesbefore the builder APIs can access any sourcemodel: Eloquent model classwith: relations to eager loadpublic_scope: optional scope applied when rendering public-facing dynamic blockstitle_field/subtitle_field: fields used in picker cardstranslated_title/translated_subtitle: whether to use TypiCMS translations when availableimage_relation/image_attribute: how preview images are resolvedurl_method: public URL method for rendered cardsedit_url_method: admin edit URL method for picker actionsbrowse_route: optional route name, with{locale}placeholder supportsort_column: column used for recent ordering
Public Sanitization
Layr sanitizes the compiled public HTML and CSS before rendering:
- dangerous tags like
script,style,object,embed, andformare removed - inline event handlers are removed
- links, media sources, and iframe sources are scheme-checked
- inline styles and stylesheets are filtered to remove dangerous CSS tokens such as
expression(...),javascript:, and@import
For iframe-based embeds, configure the allowed hosts in config/layr.php:
'sanitizer' => [
'allowed_iframe_hosts' => [
'www.youtube.com',
'youtube.com',
'www.youtube-nocookie.com',
'youtube-nocookie.com',
'player.vimeo.com',
],
],
Frontend build
End users do not need Node or a host-app Vite entry. The package serves its own built assets from dist/.
When maintaining the package:
npm install
npm run build
Layr's package build currently requires Node.js 20.19.0+ or 22.12.0+.
That produces:
dist/admin.jsdist/admin.cssdist/public.css
Package Tests
Layr owns its own PHP unit tests:
composer install
composer test
The tests run against a lightweight in-memory testbench setup inside the package, while the smoke test still verifies the full install flow against a fresh TypiCMS application.
Package Verification
Run the package verification flow from the Layr repo:
bash scripts/ci/verify-package.sh
This runs Composer validation, the package test suite, the frontend build, and the smoke install when PHP ext-redis is available.
The verification flow expects Node.js 20.19.0+ or 22.12.0+ for the frontend build step.
For host-app upgrade guidance, see UPGRADING.md.
Smoke Test
To verify Layr against a fresh stock TypiCMS app:
./scripts/ci/smoke-typicms.sh
That script creates a temporary TypiCMS install, requires Layr through a local path repository, migrates, and checks the install, page form integration, save request binding, and public render path.
Note: the stock TypiCMS bootstrap currently expects the PHP redis extension during package discovery, so the smoke app should run in an environment where ext-redis is available.