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 Bundle Laravel Package

rmzamora/page-bundle

A Laravel package for managing CMS-style pages in your application, bundling page models, routing, and rendering helpers so you can add editable content pages without building the plumbing yourself. Early-stage project with limited adoption; review the source and docs before relying on it in product...

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: rmzamora/page-bundle is a fork of sonata-project/page-bundle, a Symfony bundle. It is not a Laravel package and cannot be composer required into a Laravel app — its dependency chain (symfony/framework-bundle, sonata-project/admin-bundle, sonata-project/block-bundle, doctrine/orm, knp-menu) will not resolve against Laravel's container or routing. The fork is also archived, zero-star, zero-dependent, so treat it as a reference implementation, not a dependency.

Where to look first:

  • The upstream SonataPageBundle docs (sonata-project.org/bundles/page) — the fork diverges minimally and the docs are the only real guide.
  • SonataPageBundle.php, Resources/config/*.xml, and Entity/Page.php for the domain model.
  • The PageManager, SnapshotManager, and BlockManager services — these are the day-to-day API.

First use case (if you were on Symfony 3/4): install the bundle alongside SonataAdmin, then build a "Pages" admin section where editors compose pages from reusable blocks and publish snapshots. In Laravel your equivalent first use case is a Page model plus an admin resource where content is composed from ordered blocks — see below.

Implementation Patterns

What the bundle actually does, in port-able terms:

  • Page as aggregate: a Page row holds slug, title, site, template, and SEO metadata; a page_block join table attaches ordered Block rows. That is classic polymorphic block composition — in Laravel: Page hasMany PageBlock (polymorphic blockable).
  • Snapshots: publishing writes a PageSnapshot row with a JSON payload of page + blocks, and the public route renders the snapshot instead of live-edited state. In Laravel: a page_snapshots table with a payload JSON cast, render the latest published snapshot on the front end.
  • Multi-site: a Site entity plus a site selector; pages are scoped by site_id. In Laravel that maps to spatie/laravel-multitenancy or a plain site_id global scope.
  • Block services: each block type is a tagged service with a template. Laravel equivalent: a BlockRenderer registry ('hero' => HeroBlock::class) keyed off a type column, rendered via @include('blocks.'.$type) behind a small Block contract.

Practical Laravel workflow for the same thing:

  1. php artisan make:model Page -m, then PageBlock, PageSnapshot, Site.
  2. Filament resource for Page using the Builder field — this is the direct analogue of block composition and gets you ~80% of SonataPage's editing UX in an afternoon.
  3. Public route Route::get('/{page:slug}', PageController::class) resolving the latest published snapshot, wrapped in Cache::remember keyed by snapshot id.
  4. SEO: store meta_title, meta_description, og_image on the snapshot; feed spatie/laravel-sitemap from published pages.

Integration tips: keep block config in a PHP config array rather than DB schema, so adding a block type doesn't need a migration. Render blocks through Blade components (<x-block.hero :data="$block->data" />) to get the same template-swappable behaviour the bundle gets from Symfony service tags.

Gotchas and Tips

  • Do not install it. Composer will either fail outright or drag a Sonata/Symfony stack you don't want into a Laravel app. The fork has no maintainer, no security fixes, and is pinned to Symfony 3/4-era APIs.
  • Archived means dead ends: upstream Sonata moved to v4 and native bundle structure; this fork did not. Any bugfix or CVE after the archive date is simply absent.
  • Doctrine coupling — the bundle assumes Doctrine ORM entities and mappings. Eloquent has no path in without rewriting Entity/* wholesale.
  • Block registration breaks silently: blocks are wired via DI tags and XML config; add one without a matching template and you get nothing rendered and no error. If you port, use an explicit registry rather than auto-discovery.
  • Snapshot drift: editing a page after publishing does not update the public view until you republish. Editors routinely report "my change isn't live." Same trap exists in any snapshot design — surface a draft/published badge in admin.
  • Cache quirks: SonataPage caches rendered pages aggressively; bin/console cache:clear and re-publishing were the standard fix. In Laravel, tag page cache by snapshot id and bust on publish.
  • Debugging: the sonata:page:create-snapshots command and the sonata_page config tree are where most "why is it blank" issues live. Start there when reading source.
  • Extension point worth copying: the split of page (route/slug/SEO) from blocks (content) from snapshot (published state) is the genuinely reusable idea. Copy that three-table shape into Laravel and ignore the rest.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle