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

Cms Bundle Laravel Package

orbitale/cms-bundle

Orbitale CMS Bundle is a lightweight, extensible content management bundle for Symfony. It provides pages, menus, and reusable content blocks with admin tooling, Twig integration, SEO-friendly URLs, and a flexible structure for building and managing multilingual websites.

View on GitHub
Deep Wiki
Context7

Getting Started

Coming from Laravel, the first thing to internalize is that this is a Symfony bundle, not a Laravel package. There is no package auto-discovery, no service provider, no Blade, and no Eloquent. You will be working inside a Symfony application (or standing up a small one as a headless content service). Treat that as the baseline for everything below.

Version gate first. As of v4.1.0 the bundle requires Symfony 5.3 minimum (previously 5.0) and now supports Symfony 6.0. If your app is on Symfony 5.0–5.2 you cannot take 4.1.0 without upgrading Symfony first; pin 4.0.* if you are stuck. On a fresh Symfony 6 Flex app you can install the latest normally.

Minimal setup:

  1. composer require orbitale/cms-bundle in a Symfony Flex app (Symfony 5.3+ or 6.0).
  2. Register the bundle in config/bundles.php:
    Orbitale\CmsBundle\OrbitaleCmsBundle::class => ['all' => true],
    
  3. Import the bundle's routing (check vendor/orbitale/cms-bundle/Resources/config/routing* for the exact file name) into config/routes.yaml:
    orbitale_cms:
        resource: '@OrbitaleCmsBundle/Resources/config/routing.yaml'
    
  4. Wire the Doctrine mapping and create the tables — you own the schema, so either run the vendor migrations or doctrine:schema:update --force in dev:
    php bin/console doctrine:schema:update --force
    

Where to look first: the bundle's Page and Block entities, the BlockType base class (the extension point you will spend most of your time on), and the Twig extension that renders blocks. Then the admin controllers — that is your CRUD UI for free.

First use case: build one custom BlockType (a text block), create a page in the admin, attach the block, and render the page from a controller. That single loop — model page → compose blocks → render — is 90% of how the package earns its keep.

Implementation Patterns

Block types are the unit of work. A block type is a small class that pairs a Symfony FormType (the authoring UI) with a Twig template (the front-end output). Register it as a tagged service or in the bundle config, give it a machine name, and you have a new content component:

class TextBlockType extends AbstractBlockType
{
    public function getName(): string { return 'text'; }
    public function getFormType(): string { return TextBlockFormType::class; }
    public function getTemplate(): string { return 'blocks/text.html.twig'; }
}

Keep the block config to flat scalars (strings, ints, arrays of IDs). Anything structured in the form becomes structured in the database, and schema drift is painful later.

Page composition. Pages hold an ordered list of blocks. Rendering is a loop over page.blocks, delegating each block to its own template via the bundle's render helper (the Twig function exposed by the bundle's extension — orbitale_cms_render_block and friends, depending on version):

{% for block in page.blocks %}
    {{ orbitale_cms_render_block(block) }}
{% endfor %}

A catch-all Symfony route (/{slug}) that loads a Page by slug and falls through to a 404 is the simplest front-end mapping.

Custom block types for domain data. The pattern that pays off is a block that stores IDs and renders via a repository — e.g. a "product carousel" block that saves a list of SKUs and resolves them at render time. This keeps editors in control of placement without duplicating product data in the CMS.

Headless mode (the realistic Laravel bridge). If the front end is Laravel and the content must live in the CMS, run the bundle as a separate Symfony service, expose pages/blocks as JSON from a thin controller (or API Platform), and consume it with an HTTP client on the Laravel side. Cache the JSON with a short TTL, invalidate on block save. Do not attempt to render Twig templates from Laravel. Given 4.1.0's Symfony 6 support, building this sidecar on a current Symfony LTS is now a realistic option rather than a compatibility gamble.

Admin reuse. The bundled admin gives you page/block CRUD. Extend it by overriding templates (templates/bundles/OrbitaleCmsBundle/...) and adding your custom block types — not by rewriting entities unless you have to.

Caching. Rendered pages are the obvious cache boundary. Cache the compiled HTML keyed by page id + updated timestamp, and hook a Doctrine lifecycle listener on Block/Page to purge. Without this, every block render is a set of queries.

Gotchas and Tips

  • This is not a Laravel package. No php artisan vendor:publish, no facade. If your project is Laravel-only, the correct answer is usually "don't" — stand up a Symfony sidecar or pick a headless CMS. Trying to shoehorn Symfony bundle entities into Eloquent is a bad trade.
  • v4.1.0's BC break is in constraints, not code. The jump to a Symfony 5.3 floor will break your composer update on 5.0–5.2 projects rather than at runtime. Decide explicitly: upgrade Symfony, or pin 4.0.* and accept you are off the supported path. There is no shim.
  • Maintenance risk is reduced, not gone. 4.1.0 added Symfony 6 support and a CI matrix across multiple PHP/Symfony versions, which is the single best signal you can get from a low-traffic bundle — but it remains a small project with few stars and no dependents. Pin exact versions, mirror the CI matrix's supported combinations in your own composer.json, and keep the fork option open. Read composer.json constraints rather than trusting the release notes alone.
  • You don't own the entities. Bundle entities are mapped inside vendor. Adding columns means entity inheritance, mapping overrides, or a fork. Decide early which of those you're signing up for.
  • Block config schema drift. Changing a form field rarely migrates stored block data. When you rename or restructure a block's config keys, write a one-off script to rewrite existing Block rows.
  • Naming is a contract. Block type names are persisted keys on rows. Renaming a block type orphans existing content — add aliases or migrate, don't just rename the class.
  • Admin route collisions. If your host app already owns /admin, adjust the imported route prefix and your security firewall. The admin is protected by the app's firewall, not the bundle's.
  • Debugging rendering. Exceptions surface from the block type's template, not the page template, and only for blocks actually on the page. Use the Symfony profiler's Twig panel; if a page renders blank, check that each block type service is registered and its name matches what's stored.
  • Symfony 6 upgrade checklist. If you're moving the host app to 6.0 to take advantage of 4.1.0, do the Symfony 6 upgrade first and confirm the bundle boots; then re-verify your custom BlockType services are still autoconfigured, since tag/service defaults differ subtly across 5.3 → 6.0.
  • Extension points to rely on: custom BlockType services, Twig template overrides, Doctrine event listeners for cache invalidation, and a JSON controller for headless consumption. These four cover most day-to-day needs without touching the vendor code.
  • i18n and workflows are thin. If you need translated content or editorial approval states, verify current support before committing — likely you'll build it on top via extra fields or a state column on Page.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core