Installation
composer require cleverage/layout-bundle
Add to config/bundles.php:
return [
// ...
Cleverage\LayoutBundle\CleverAgeLayoutBundle::class => ['all' => true],
];
First Layout File
Create a YAML layout file (e.g., config/layouts/base.yml):
layout:
blocks:
header:
code: "@App/Block/HeaderBlock"
position: absolute
top: 0
left: 0
content:
code: "@App/Block/ContentBlock"
position: relative
top: 50px
First Block Class
Create a block (e.g., src/Block/HeaderBlock.php):
namespace App\Block;
use Cleverage\LayoutBundle\Block\AbstractBlock;
class HeaderBlock extends AbstractBlock
{
public function render()
{
return $this->renderView('blocks/header.html.twig');
}
}
Render the Layout In a controller:
use Cleverage\LayoutBundle\Layout\LayoutManager;
public function index(LayoutManager $layoutManager)
{
$layout = $layoutManager->getLayout('base');
return new Response($layout->render());
}
Dynamic Layout Composition
Use the bundle to define reusable layouts (e.g., admin.yml, public.yml) and swap them via configuration or runtime logic.
Extend Layouts
Define a child layout (config/layouts/admin.yml):
extends: base
layout:
blocks:
sidebar:
code: "@App/Block/AdminSidebarBlock"
position: absolute
right: 0
Override Blocks Reuse parent blocks while overriding specific ones:
extends: base
layout:
blocks:
header:
code: "@App/Block/AdminHeaderBlock" # Override
footer:
code: "@App/Block/DefaultFooterBlock" # Inherit from parent
Dynamic Block Registration Register blocks programmatically in a service:
$container->set('app.block.custom', function () {
return new CustomBlock();
});
Parameterized Blocks Pass parameters via YAML:
blocks:
content:
code: "@App/Block/ContentBlock"
params:
title: "Welcome"
items: ["item1", "item2"]
Access in block:
$this->getParameter('title'); // "Welcome"
Slot-Based Layouts Use slots for flexible content injection:
layout:
slots:
main:
blocks:
- "@App/Block/Slot1Block"
- "@App/Block/Slot2Block"
Embed Blocks in Twig Render a layout in a Twig template:
{{ render_layout('base') }}
Pass Context to Layouts
$layout = $layoutManager->getLayout('base', [
'user' => $user,
'theme' => 'dark'
]);
Cache Invalidation Clear cache when layouts/blocks change:
php bin/console cache:clear
Or programmatically:
$this->get('cleverage_layout.cache')->invalidateAll();
Custom Cache Keys Override cache key generation in a custom block:
public function getCacheKey()
{
return parent::getCacheKey() . '-custom-suffix';
}
Circular Dependencies
symfony/var-dumper to debug.Block Not Found
code: "@App/Block/NonExistentBlock" throws ServiceNotFoundException.services.yaml).Parameter Overrides
!merge in YAML to preserve parent values:
layout:
params: !merge
<<: *parent_params # Inherit
new_param: "value" # Override
Twig Auto-Reloading
config/packages/twig.yaml during development:
twig:
cache: false
Dump Layout Structure Use the debug command:
php bin/console debug:cleverage-layout
Log Block Rendering
Enable debug mode in config/packages/dev/cleverage_layout.yaml:
cleverage_layout:
debug: true
Cache Key Inspection
Override getCacheKey() in a block to log keys:
public function getCacheKey()
{
$key = parent::getCacheKey();
error_log("Cache key: " . $key);
return $key;
}
Custom Block Types
Extend AbstractBlock to add behavior:
class ConditionalBlock extends AbstractBlock
{
public function render()
{
if ($this->getParameter('condition')) {
return parent::render();
}
return '';
}
}
Layout Events Listen for layout rendering events:
// config/services.yaml
services:
App\EventListener\LayoutListener:
tags:
- { name: kernel.event_listener, event: cleverage_layout.render, method: onRender }
Custom Positioning Logic
Override getPosition() in a block for dynamic placement:
public function getPosition()
{
return $this->getParameter('is_sticky') ? 'fixed' : 'relative';
}
YAML Anchors Reuse common configurations with YAML anchors:
defaults: &defaults
position: relative
top: 0
layout:
blocks:
header:
<<: *defaults
code: "@App/Block/HeaderBlock"
Global Parameters
Define global parameters in config/packages/cleverage_layout.yaml:
cleverage_layout:
global_params:
site_name: "My Site"
version: "1.0"
Access in blocks via $this->getGlobalParameter('site_name').
Environment-Specific Layouts
Use Symfony’s %env% in YAML:
layout:
blocks:
footer:
code: "@App/Block/FooterBlock_%kernel.environment%"
How can I help you explore Laravel packages today?