Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Page Layout Bundle Laravel Package

it-blaster/page-layout-bundle

A PHP bundle for configurable page layout management, letting you define layout templates and reusable blocks to compose and render page structure consistently across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

The first thing to establish is that this is a Symfony + Sonata Admin bundle, not a Laravel package. There is no service provider, no config/page-layout.php to publish, no Blade views. So "getting started" for a Laravel developer means reading it, not requiring it.

Minimal steps:

  1. Clone the repo to a scratch directory — do not add it to composer.json.
  2. Read composer.json first. It answers the only two questions that matter before anything else: which Symfony major, which Sonata Admin major, and whether Gridstack.js is a declared dependency or a vendored compiled asset.
  3. Read the README.md, then walk the bundle skeleton in this order:
    • src/*Bundle.php — what it registers.
    • src/DependencyInjection/*Extension.php + Resources/config/* — the config tree and service wiring; this is where layout configuration is centralised.
    • Resources/views/** — the Twig templates, and the template contract (which block/variables a layout expects).
    • Resources/public/** — the Gridstack JS wiring. This is the only part likely worth copying.
    • Entity/ or Document/ + Admin/ — how a saved layout is persisted and exposed in Sonata.
  4. Extract the layout JSON shape into a note. That schema is the reusable artefact.

First use case: a read-only renderer in Laravel. Create a page_layouts table with a json column, paste one of the bundle's example layouts into a seeder, and write a Blade component that walks the JSON and emits Bootstrap row/col-* markup. You get the value of the idea in an afternoon without touching Gridstack.

Only if you are genuinely on Symfony/Sonata: composer require, register in config/bundles.php, verify assets are published and built, then exercise it on a staging admin before anything else.

Implementation Patterns

Reference extraction (the recommended Laravel path). Treat the repo as a spec, not a dependency. Copy three things: the Gridstack init options, the change/added/removed event handlers that serialise the grid, and the persisted JSON shape. Rebuild the UI as a Filament custom field or a Livewire component. Reimplement the Twig templates in Blade — the translation is mechanical but every Sonata block() call must be replaced with your own renderer.

Layout/content split as the architectural contract. Persist structure, not markup. A workable shape:

{ "version": 1,
  "grid": [ { "id": "a1", "x": 0, "y": 0, "w": 6, "h": 2, "widget": "hero",
              "settings": { "headline": "..." } } ] }

The widget key points at your own Blade partial; settings is content. This keeps the editor replaceable and is the single decision that makes the package worth studying.

Renderer-first, editor-second. Build and ship the read-only Blade renderer before the editor exists. Most layout bugs (collapsed columns, empty rows, mobile stacking) surface at render time, and you want them found against a hand-written JSON fixture rather than through a drag-and-drop UI.

Editor wrapper. If you do port the UI, wrap Gridstack in a thin module with two exported functions — mount(el, layout) and serialize() — and keep all Gridstack API calls inside it. Upstream Gridstack has broken its API across majors ($(el).gridstack(...) → GridStack.init(...)); an abstraction layer is the difference between a one-file upgrade and a rewrite.

Draft/publish on layouts. Because the payload is a JSON blob, versioning is cheap: keep draft_json and published_json columns, and let the renderer only ever read published_json. This also gives you an audit trail for free.

Schema versioning. Stamp version on every saved layout and write a migration for every shape change. Without this, an editor change silently orphans stored layouts.

Sonata path (if applicable). Register the admin service, map the form type, and verify the Twig template override path — Symfony resolves bundle view overrides by naming convention, which is your cleanest extension point.

Gotchas and Tips

  • The stack mismatch is the headline. A composer require into a Laravel app will not boot and will drag in Sonata's dependency graph. Decide "port the concept vs. adopt the package" before estimating anything.
  • Asset pipeline assumptions. Bundles of this vintage typically assume Symfony Webpack Encore. Under Vite, expect a rebuild, not a config tweak. Check whether the shipped JS is source or compiled — if compiled, you cannot upgrade Gridstack without forking.
  • Gridstack init on hidden containers. Classic failure: the grid mounts inside a collapsed tab or modal, measures zero height, and everything stacks at x:0. Force a re-layout when the container becomes visible.
  • DOM order ≠ visual order. Free-form positioning lets editors place content in an order that reads badly for screen readers and crawlers. Mitigate by sorting nodes by y, then x, when emitting markup — or accept the limitation explicitly up front.
  • Empty columns collapse. Bootstrap removes zero-width columns and rows; a grid saved with gaps renders differently from the editor preview. Sanitise empty nodes on save.
  • JSON drift. Store widget identifiers as strings resolved by a registry (['hero' => HeroWidget::class]), never as class names — class renames are otherwise a data migration.
  • No upstream safety net. Zero dependents, five stars, no visible CI. Assume no patches. Pin, vendor, and write your own feature test asserting "this JSON renders this HTML" so a future refactor is caught.
  • Debugging tip. When the editor misbehaves, log the serialised output on every change event rather than inspecting the DOM — the JSON is the contract; the DOM is a projection of it.
  • Config quirks. Symfony bundle config lands under a snake_case key derived from the bundle name, and services are usually private by default. If you are reverse-engineering behaviour, start from Resources/config/services.* rather than the classes.
  • Extension points worth knowing: Twig template overrides by path convention, the form type for the admin edit screen, and whatever "widget/block" service tag the bundle uses — that tag is where you register your own renderers.
  • Licence is clean (MIT) — the only blockers are engineering. Forking is legally unencumbered, which is what makes the reference-extraction path viable.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package