Bootstrap page layout for sonata, based on gridstack.js

Installs: 14 273

Dependents: 0

Suggesters: 0

Security: 0

Stars: 5

Watchers: 11

Forks: 1

Open Issues: 0



dev-master 2017-05-31 13:27 UTC

This package is not auto-updated.

Last update: 2024-04-13 16:18:15 UTC


Bootstrap page layout for Symfony Sonata Admin Bundle, based on gridstack.js


Simple editor in Sonata Admin

Resize and drag blocks Simple edit Easy change any properties

Bootstrap grid as result

Bootstrap grid as result


With Composer

composer require it-blaster/page-layout-bundle

Add post install/update script to composer.json

installGridStackJs just make system call bower install in bundle's directory

    "scripts": {
        "post-install-cmd": [
        "post-update-cmd": [

Register the bundle in your AppKernel.php

new Etfostra\PageLayoutBundle\EtfostraPageLayoutBundle(),

Edit config.yml

Add EtfostraPageLayoutBundle to assetic.bundles

        - EtfostraPageLayoutBundle


All configs are optional, default values present below, config.yml:

    grid_settings: #
        always_show_resize_handle: false
        animate: true
        auto: true
        cell_height: 80
            handle: '.grid-stack-item-content'
            scroll: true
            appendTo: 'body'
        handle: '.grid-stack-item-content'
        handle_class: ''
        height: 0
        float: false #
        item_class: 'grid-stack-item'
        min_width: 768
        placeholder_class: 'grid-stack-placeholder'
        placeholder_text: ''
            autoHide: true
            handles: 'se'
        static_grid: false
        vertical_margin: 10
        width: 12
        item_min_width: 4
    properties: # data for generating additional widget properties (options in select)
            xs: XS — Extra small devices
            sm: SM — Small devices Tablets
            md: MD — Medium devices Desktops
            lg: LG — Large devices Desktops
        front_layout: EtfostraPageLayoutBundle:Frontend:page_layout.html.twig


Insert page_layout field in Sonata Admin class

class YourAdmin extends Admin
    protected function configureFormFields(FormMapper $formMapper)
            ->add('your_text_field', 'page_layout', array(
                'required' => false,
                'choices'  => array(
                    // Key and value can be any string, it's up to you.
                    // This keys will be available later in WidgetRenderer::setWidgets
                    'CurrentPage:'          => 'Current page content',
                    'Widget:feedbackform'   => 'Feedback form',
                    'Widget:leftmenu'       => 'Left menu',

From now, you can edit and save (to your_text_field) data of grid in Sonata Admin.

Frontend layout generation

For layout generation we must call and configure service form controller

$layout = $this->get('')
    ->setLayoutData( $your_text_field )
    ->setWidgetRenderer( $renderer )

But now we have two undefined variables! It's ok, how to define it:

$your_text_field = $yourObject->getYourTextField(); // It's simple, this is data from your your_text_field, that we edit in Sonata Admin
$renderer = $this->get('widget_renderer'); // This is more complex, we must implement our service widget_renderer 

Define this new service in services.yml, arguments are optional and depends on realization

        class: Your\AppBundle\Service\WidgetRenderer
            - @templating

Time to create our new renderer service, call it WidgetRenderer

namespace Your\AppBundle\Service;

use Etfostra\PageLayoutBundle\Services\WidgetRenderInterface;
use Symfony\Component\Templating\EngineInterface;

class WidgetRenderer implements WidgetRenderInterface
    protected $widgets;
    protected $templating;
    public function __construct(EngineInterface $templating)
        $this->templating = $templating;
     * At this we must fill $this->widgets array with html rendered widgets
    public function setWidgets(array $widgets) // $widgets example: array('CurrentPage:', 'Widget:feedbackform', 'Widget:leftmenu') 
        foreach ($widgets as $widget_id) {
            $this->widgets[$widget_id] = $this->templating->render('YourAppBundle:Widget:widget.html.twig', array(
                'widget_id' => $widget_id,
    public function getWidget($widget_id)
        if (isset($this->widgets[$widget_id])) {
            return $this->widgets[$widget_id];

        return null;

It's very simplified example, you can create more complex realization, depends on your widget system.