Overview

PrestaCms content is managed through blocks. Every pages and theme are divided in zones which contains blocks of different types.

Block system is based on CMFBlockBundle which extends SonataBlockBundle.

Before going further, we suggest you read the SonataBlockBundle documentation which explain a lot of useful things.

Configuration

By default, you can add every type of block you want in a page without any specific configuration.

Exclude a block from choice list

However, for some reason, if you want to restrict the choice of adding blocks in your page, this is possible like follows:

presta_cms_core:
    ...
    blocks:
        global:
            excluded:
                - presta_cms.block.ajax

Force some blocks to display in choice list

Maybe, on the contrary, if you want to force the display of only one (or several) block to add in the page, you can do it in this way:

presta_cms_core:
    ...
    blocks:
        global:
            accepted:
                - presta_cms.block.ajax
                - presta_cms.block.sitemap

Add configuration for specific zone or container

Also, you can configuration a behavior for a specific zone for example.

presta_cms_core:
    ...
    blocks:
        global:
            accepted:
                - presta_cms.block.ajax
                - presta_cms.block.sitemap
        content:
            excluded:
                - presta_cms.block.simple

Here, we excluded the simple block from blocks choice list just for the zone named “content”. All others zones will use the “global” configuration. If no “global” configuration is found, no restriction will be applied on the blocks.

The same thing is possible with the container block, if you use their type.

presta_cms_core:
    ...
    blocks:
        global:
            accepted:
                - presta_cms.block.ajax
                - presta_cms.block.sitemap
        presta_cms.block.container:
            excluded:
                - presta_cms.block.simple

Block types

PrestaCMSCore handle basic block types :

  • Simple : A simple block contains a title, a text and a link to another CMS page.

Simple block

  • Sitemap : Sitemap block render a navigation under a defined root page. It can be used for a footer or sidebar navigation.

Sitemap block

  • Container : A container allow you to format page rendering. Multiple format are available : 50/50, 1/3 - 2/3, … Containers can contain any kind of other blocks.

Container block

  • Page children : this block display a list of page children with a title and a description. It is usually used for landing pages.

Page children block

  • Ajax: Display some ajax content. This allows to cache a full page and only refresh the block with ajax. You have to include the Resources/public/js/prestacmscore.js file in your theme layout to use it. An example is available here : sandbox - Left sidebar layout.

Other bundle can easily add more block types to your application, for example you can have a look at PrestaCMSMediaBundle which adds special blocks to render medias.

 Block base service

If you have read the SonataBlockBundle documentation you know that the two main elements of a block are template and service class (responsible of rendering the block).

Common block features have been centralized in BaseBlockService so every new block service should extend it.

BaseBlockService commons features are :

  • provide the translator
  • automatically load the template
  • preview : block which used javascript or complex css features to render should provide a preview image to display it in the administration screen (for example carousel).
  • settingsRoute : block which displays application entities (for example blog posts) should provide a settingsRoute which is the sonata admin code of the entities listing. A link to the corresponding admin list will be displayed in the page administration.

Build your first block

Let’s create a new block for listing blog post. Blog post have a custom administration done with sonata.

Our bundle will have an editable title and an option to set the number of post to display.

We supposed that your bundle is in src/Presta/Blog and Blog Post CRUD is already done.

The service

Create a service class which extends the base one.

As our block is linked to Blog Post, we will set the settingRoute to link it, we will also add a preview.

As we need to make query to Post repository, we will use getAdditionalViewParameters method to give additional parameters to the view.

We need to configure the edit form to add an entry for the number of posts to display and as we need a default number we will set it in the getDefaultSettings()

So here is how the code looks like :

File : src/Presta/Blog/Block/Post/ListBlockService.php

<?php
namespace Presta\Blog\Block\Post;

use Sonata\BlockBundle\Model\BlockInterface;
use Presta\CMSCoreBundle\Block\BaseBlockService;
use Doctrine\ORM\EntityRepository;

/**
 * @author Nicolas Bastien <nbastien@prestaconcept.net>
 */
class ListBlockService extends BaseBlockService
{
    /**
     * @var string
     */
    protected $preview = 'bundles/prestablog/theme/sandbox/admin/img/block/blog_post_list.jpg';

    /**
     * @var string
     */
    protected $settingsRoute = 'admin_presta_blog_post_list';

    /**
     * @var string
     */
    protected $template = 'PrestaBlogBundle:Block\Blog\Post:block_list.html.twig';

    /**
     * @var EntityRepository
     */
    protected $repository;

    /**
     * @param $container
     */
    public function setContainer($container)
    {
        $this->repository = $container->get('doctrine')->getRepository('PrestaBlogBundle:Blog\Post');
    }

    /**
     * {@inheritdoc}
     */
    protected function getAdditionalViewParameters(BlockInterface $block)
    {
        $settings = array_merge(
            $this->getDefaultSettings(),
            $block->getSettings()
        );

        $settings['posts'] = $this->repository->getActiveList($settings['nb_posts']);

        return $settings;
    }

    /**
     * {@inheritdoc}
     */
    public function getFormSettings(FormMapper $formMapper, BlockInterface $block)
    {
        return array(
            array('nb_posts', 'integer', array('required' => false, 'label' => $this->trans('form.label_nb_posts')))
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getDefaultSettings()
    {
        return array(
            'nb_posts' => 0
        );
    }
}

The template

Second part is to build the corresponding template.

As we set the $template variable in the block service, we have to add PrestaBlogBundle:Block\Blog\Post:block_list.html.twig file.

Every template should extends the default one which adds default structure and ids.

{% extends 'PrestaCMSCoreBundle:Block:base_block.html.twig' %}

{% block block %}
    <h2>{{ settings.title }}</h2>
    <ul id="post-list">
        {% for post in posts %}
            <li>
                <h3>{{ post.tile }}</h3>
                <p>{{ post.description }}</p>
            </li>
        {% endfor %}
    </ul>
{% endblock %}

Configuration

Now our block is nearly over, we just need to register the new service and to add a special tag for PrestaCMS.

File : /src/Presta/BlogBundle/Resources/config/block.yml

services:
    ...
    #Blocks
    presta_blog.block.post.list:
        class: Presta\BlogBundle\Block\Post\ListBlockService
        parent: presta_cms.block.base
        tags:
            - {name: sonata.block}
            - {name: presta_cms.block}
        calls:
            - [ setContainer, [@service_container]]

Tag presta_cms.block allow BlockManager to retrieve it and to use it in the available block list.

You can also do this using XML language.

File : /src/Presta/BlogBundle/Resources/config/block.xml

<container xmlns="http://symfony.com/schema/dic/services"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <parameters>
        <parameter key="presta_cms.block.list.class">Presta\CMSMediaBundle\Block\ListBlockService</parameter>
    </parameters>

    <services>
        <service id="presta_cms.block.list" class="%presta_cms.block.list.class%" parent="presta_cms.block.base">
            <tag name="sonata.block"/>
            <tag name="presta_cms.block"/>
        </service>
    </services>
</container>

And some translation for the admin interface : PrestaCMSCoreBundle.en.yml

block.title.presta_blog.block.post.list: Latest posts
    block.description.presta_blog.block.post.list: This blocks displays lasted blog posts

→ Let’s continue with block advanced features.


Want do contribute ? Just fork and edit it!