kitpages/cms-bundle
Kitpages CMS Bundle is a Symfony content management bundle for building and editing websites with reusable content blocks, pages, and layouts. It provides an admin interface and integrates with Symfony apps to simplify content creation and publishing.
Important first step: kitpages/cms-bundle is a Symfony 2.x/3.x bundle, not a Laravel package. If you are on Laravel you cannot install it directly; the closest path is to run a Symfony app alongside Laravel, or port the concepts (Page/Zone/Block entities plus a renderer) manually. Everything below assumes a Symfony application.
Minimal steps:
composer require kitpages/cms-bundle in a Symfony 2.8/3.x project (PHP 5.6–7.x era).app/AppKernel.php (and any siblings it pulls in — typically KitpagesFileBundle / KitpagesUtilBundle, plus optional SonataAdminBundle / IvoryCKEditorBundle for administration).# app/config/routing.yml
kitpages_cms:
resource: "@KitpagesCmsBundle/Resources/config/routing.yml"
prefix: /
# app/config/config.yml
imports:
- { resource: "@KitpagesCmsBundle/Resources/config/services.yml" }
app/console doctrine:schema:update --force (or generate a migration). The bundle expects tables for pages, zones/blocks, and a URL map.Kitpages\CmsBundle\Entity\Page, Zone, Block, and UrlMap — this is the whole mental model. Then read Kitpages\CmsBundle\Manager\* and the Twig extension.First use case: create a Page with a slug and a UrlMap, attach a Zone named main, drop a text block into it with the admin UI, then render it in a controller/template with the bundle's Twig helper (e.g. kitpages_cms_render_zone(...) / kitpages_cms_page(...), depending on version). Visit the mapped URL and confirm the block renders.
Page → Zone → Block composition. A page is a container; zones are named slots in your layout; blocks are typed pieces of content inside a zone. In your base template:
{# layout.html.twig #}
<div id="main">{{ kitpages_cms_render_zone(page, 'main') }}</div>
<aside>{{ kitpages_cms_render_zone(page, 'sidebar') }}</aside>
Keep zone names stable and semantic — they become the contract between designers and content editors, so changing them later means re-authoring content.
Route by URL map, not by controller per page. Instead of one controller per static page, register the page in UrlMap and let the bundle's dispatcher resolve /{path}. This is the core day-to-day workflow: marketing pages never require a deploy.
Custom block types via tagged services. The idiomatic extension point is to add your own block renderer and tag it so the renderer registry picks it up:
services:
app.block.cta:
class: AppBundle\Cms\CtaBlockRenderer
tags:
- { name: kitpages_cms.block, alias: cta }
Then implement whatever interface your version exposes (BlockRendererInterface-style: render(Block $block, array $options)). Store per-block config as JSON/serialized data in the block's data column and read it in the renderer. Use this for anything dynamic — product carousels, forms, embeds — rather than stuffing raw HTML into text blocks.
Subclass the base entities when you need fields. Standard pattern is to create AppBundle\Entity\Page extends Kitpages\CmsBundle\Entity\Page and point Doctrine at your class via resolve_target_entities / the bundle's config, so you can add SEO fields, categories, or workflow status without forking.
Override templates, don't edit vendor. Put replacements in app/Resources/KitpagesCmsBundle/views/.... This applies to both the front-end block templates and the admin screens.
Integrate with your app's security and cache layers. Wrap the admin routes in a firewall role (ROLE_CMS_ADMIN), and add an HTTP cache / listener that clears page cache entries when a Page or Block is persisted. Because content changes bypass deploys, cache invalidation on save is the single most important integration point.
Block for custom types, register the subclasses in the discriminator map, otherwise the renderer will silently fall back to the base type and your custom template never fires./about vs /about/). Add a unique constraint or a validation step, and decide on a canonical slash policy up front.assets:dump/assetic:dump in prod and don't be surprised by 404s in dev if the bundle's assets weren't published.page_slug route fallback, Blade components per block type). Given the package's age and zero dependents, that port is often the better assessment outcome than adoption.How can I help you explore Laravel packages today?