sonata-project/page-bundle
SonataPageBundle adds site and page management to Symfony apps, using a container-based page system and block services. Build and manage pages across multiple sites, integrate with Sonata blocks, and control layout, routing, and page publishing.
Installation:
composer require sonata-project/page-bundle
Add to config/bundles.php:
SonataProject\PageBundle\SonataPageBundle::class => ['all' => true],
Database Migrations:
Run php bin/console doctrine:migrations:diff and php bin/console doctrine:migrations:migrate to create the required tables (page, page_slot, page_block, etc.).
First Use Case: Create a page via CLI:
php bin/console sonata:page:create --name="Homepage" --slug="home" --enabled=true
Access the admin interface at /admin/page (ensure SonataAdminBundle is installed).
/admin/page for CRUD operations.config/packages/sonata_page.yaml (default settings).templates/sonata/page/page.html.twig for rendering logic.src/Sonata/PageBundle/Block/ for reusable components.Page Creation & Management:
$page = new Page();
$page->setName('About Us');
$page->setSlug('about');
$page->setEnabled(true);
$manager = $this->getDoctrine()->getManager();
$manager->persist($page);
$manager->flush();
Block Integration:
Sonata\PageBundle\Model\BlockInterface for custom blocks:
namespace App\Block;
use Sonata\PageBundle\Model\BlockInterface;
class CustomBlock implements BlockInterface {
public function execute() { /* ... */ }
}
services.yaml:
services:
app.block.custom:
class: App\Block\CustomBlock
tags:
- { name: sonata.page.block }
Page Rendering:
{% render page %}
vendor/sonata-project/page-bundle/Resources/views to templates/sonata/page/.Routing:
sonata.page.canonical route. Override with:
# config/routes.yaml
sonata_page_homepage:
path: /
defaults: { _controller: 'SonataPageBundle:Page:homepage' }
config/packages/sonata_page.yaml for minimal config.SonataAdminBundle for a full CMS.sonata.page.block.service to fetch blocks dynamically:
$blockService = $this->get('sonata.page.block.service');
$blocks = $blockService->getBlocks($page);
sonata.page.pre_persist):
use Sonata\PageBundle\Event\PageEvent;
public function onPrePersist(PageEvent $event) {
$page = $event->getPage();
$page->setMetaDescription('Default meta');
}
Cache Issues:
php bin/console cache:clear
sonata.page.cache is configured in framework.yaml:
framework:
cache:
app: cache.adapter.redis
Block Ordering:
position field. Update via:
$block->setPosition(10); // Higher = lower in UI
Slug Conflicts:
PageAdmin:
$page->setSlug(uniqid('page_', true));
Twig Debugging:
{% debug page %} to inspect page/block data.$this->get('logger')->debug('Blocks:', $blocks->toArray());
config/packages/dev/monolog.yaml:
handlers:
sonata_events:
type: stream
path: "%kernel.logs_dir%/sonata_events.log"
level: debug
Custom Block Types:
Sonata\PageBundle\Block\BaseBlockService for custom logic.class CustomBlockService extends BaseBlockService {
public function getType() { return 'custom'; }
public function execute($block, $page) { /* ... */ }
}
Page Metadata:
Page entity:
// src/Entity/Page.php
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Page extends BasePage {
#[ORM\Column(type: 'string', nullable: true)]
private $customField;
}
Routing Overrides:
sonata.page.canonical to false in config:
sonata_page:
canonical: false
Security:
sonata.page.security.handler:
sonata_page:
security_handler: app.page_security_handler
Implement Sonata\PageBundle\Security\PageSecurityHandlerInterface.How can I help you explore Laravel packages today?