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

octave/cms-bundle

Octave CMS Bundle is a modular content management package for Laravel. It offers page, post, and media management with a flexible block editor, admin scaffolding, routing, and Blade components. Its pluggable architecture lets you extend or replace any part to build content-driven sites quickly.

View on GitHub
Deep Wiki
Context7

Getting Started

Read composer.json before you read anything else. The name says cms-bundle and the description says Symfony3, so the first thing to establish is whether you actually have a Laravel package or a Symfony bundle that the surrounding assessments have optimistically described as one. That single fact determines the entire integration story:

  • If it ships a ServiceProvider and illuminate/* constraints, follow the Laravel package contract below.
  • If it ships a Bundle class, DependencyInjection/Extension, and Resources/config/services.yml, you are not installing a Laravel package — you are either running a Symfony sidecar or porting the internals.

Minimal happy path (Laravel-shaped):

composer require octave/cms-bundle
php artisan vendor:publish --provider="Octave\Cms\CmsServiceProvider"
php artisan migrate

Then register the provider (if not auto-discovered), seed or create an admin user, and hit whatever admin route the package registers — check php artisan route:list | grep -i cms rather than assuming a path.

Where to look first, in order:

  1. The service provider / DI extension — this is the real documentation. Count what it binds, what it tags, and what it registers globally (routes, middleware, view namespaces, auth guards).
  2. The config tree — content types and page layouts are config-driven per the description, so the shipped config file is your API surface.
  3. Migrations — confirm whether they create tables or Schema::table(...) an existing one. This is the detail that turns a one-day spike into a multi-sprint remediation.
  4. Resources/views (or resources/views) — the block templates define the composition model more clearly than any prose will.

First use case to target: a single brochure page composed of three or four nested blocks with SEO metadata, rendered by a route you control. This exercises the whole stack — content type config, block nesting, persistence, template resolution, metadata — without touching auth, media, or revisions. If that works end-to-end you have a valid prototype; if it fights you, you have your answer cheaply.

Implementation Patterns

Keep the CMS behind a content interface. Even in a spike, define a narrow port in your app (PageRepository, ContentRenderer) and let the bundle satisfy it. This is the difference between "we tried a package" and "we are now married to a package with 1 star." It also makes the build-vs-buy comparison at the end of the spike an afternoon rather than a rewrite.

Define content types as configuration, not code. The bundle's selling point is configurable fields and validation without boilerplate. Lean into it — one config block per content type, fields declared declaratively. If you find yourself writing custom entities per page type, you have left the package's value proposition and should be asking why you are still using it.

Compose pages from blocks, and keep blocks dumb. A block should receive data and render; it should not query. Nesting is supported, which is where the value is (hero → card grid → CTA), but nesting plus per-block queries is how CMS page loads become N+1 storms. Resolve data once in the controller or a view composer, then hand it down.

Bridge auth instead of adopting it. If the bundle registers its own guard, middleware group, or user model, do not let it own identity for the wider app. Wrap the admin routes in your existing auth/can middleware, or gate the whole admin prefix behind your own authorization check. Never let a low-visibility admin panel be the thing that decides who is an administrator.

Treat template and config publishing as a fork. Once you run vendor:publish, you own those files. Keep a cms-overrides.md listing every published file you have edited, so upgrades are a diff rather than archaeology.

Isolate routing. Namespace the admin routes under a prefix (/admin/content, not /admin if you already have one) and confirm registration order in RouteServiceProvider. Packages that register routes in boot() frequently win the race against your own catch-all or resource routes.

Read path: cache aggressively. CMS content is the most cacheable thing in the app. Page render behind a response cache keyed on page slug and updated-at timestamp gives you the scaling story the package itself does not. The admin surface is the only place query efficiency should worry you.

Standalone sidecar (if this is genuinely Symfony). Run the CMS as its own small Symfony app on its own subdomain, render pages there, and let Laravel own everything else. Ugly, but it keeps the two frameworks' routing, auth, and migration assumptions from colliding — and it makes removal a DNS change.

Gotchas and Tips

The framework mismatch is the headline gotcha. A "Symfony3 CMS" is targeting a PHP branch that reached end of life years ago. If the constraint is genuinely symfony/symfony: ~3.0, then no amount of Laravel service-provider wrapping makes it installable on a modern PHP runtime. Run composer require in a throwaway app first and let Composer tell you the truth before you read another line of documentation.

route:cache and config:cache are where it breaks. CMS bundles that register dynamic routes or read config at boot routinely work in php artisan serve and fail under production caching. Enable both caches during the spike, not after. php artisan route:cache && php artisan config:cache && php artisan serve should be step three, not a launch-week surprise.

Check whether migrations alter shared tables. If the published migrations touch a users or media table you already own, stop and decide before running them. A dedicated connection or table prefix is cheap now and impossible to retrofit later.

View namespace collisions shadow silently. If the package registers a cms:: namespace you are fine; if it publishes into a generic path or overrides common view names, you will discover it in production. php artisan view:clear then grep your Blade includes for ambiguity.

Read-only filesystems. Packages that write on boot (cache warmers, asset dumps, uploaded media into storage/) work fine locally and fail on a read-only container image behind a load balancer. Test with media on object storage and the app filesystem mounted read-only before pilot exit.

Debugging toolkit: php artisan route:list, php artisan tinker against the content models, and — if it is Symfony — bin/console debug:router, debug:container, and the profiler. Do not debug a config-driven CMS by reading templates; read the resolved config (config('cms') or debug:config) and work backwards.

Extension points to prefer, in order: service decoration/override → config-driven content types → published templates → forking the package. Each step down that list costs more to upgrade. If you find yourself editing vendor code without a fork and a path repository in place, vendorize first — with 0 dependents and 1 star, you are the maintainer whether you planned to be or not.

Media and revisions are the scope creep. Both are advertised and both are where the hidden work lives — storage adapters, cleanup, revision diffing, and restore semantics are rarely as complete as the feature list implies. Spike pages first; prove media before promising it.

Set an exit date. Note today's date and the package version. If there is no upstream release and no new dependent by a review date three to six months out, the fork becomes the product and should be budgeted as such.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
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