Symfony CMS - day 05 - Sonata Page Installation

Oct 13th, 2013

Installing Donata Page Bundle in order to finish our CMS.

Hello ! Fifth day of our tutorial on how to make a small CMS with Symfony and Sonata bundles. Previous article Sonata User Installation.

Today we’ll install Sonata Page Bundle. You can read the Sonata page documentation.

Writing tests

As we have Behat installed, we can write tests for Sonata Page install.

touch src/My/BDDBundle/Features/04-sonata-page-install.feature
Feature: sonata page installation
  In order to manage site pages
  As a smart developer
  I need to get Sonata page installed

  Scenario: Managing Sonata page elements from dashboard
    Given I am logged in as admin
    And I go to "/admin/dashboard"
    Then I should see "Pages"
    And I should see "Notification"

The result of a bin/behat –tags=”sonataPage” command will ask you to implement a new iAmLoggedInAsAdmin step. Just open src/My/BDDBundle/Features/Context/FeatureContext.php and add :

// src/My/BDDBundle/Features/Context/FeatureContext.php

     * @Given /^I am logged in as admin$/
    public function iAmLoggedInAsAdmin()
        $this->fillField('username', 'admin');
        $this->fillField('password', 'admin');

The result of a bin/behat –tags=”sonataPage” will now give you errors and that’s good !


In your composer.json file, add :

    "require": {
        "symfony-cmf/routing": "1.1.*@dev",
        "symfony-cmf/routing-bundle": "1.1.*@dev",
        "sonata-project/page-bundle": "2.3.*@dev",
        "sonata-project/seo-bundle": "1.*",
        "sonata-project/cache-bundle": "2.1.*@dev",
        "sonata-project/notification-bundle": "2.2.*@dev",


Note : the SimpleThingsEntityAuditBundle is needed for block creation on the Sonata Admin Side.

Then run a

composer update

Sonata Page Bundle configuration

Enable our new bundles in the kernel :

// app/AppKernel.php
public function registerBundles()
    return array(
        // ...
        new Sonata\PageBundle\SonataPageBundle(),
        new Sonata\SeoBundle\SonataSeoBundle(),
        new Sonata\CacheBundle\SonataCacheBundle(),
        new Sonata\NotificationBundle\SonataNotificationBundle(),
        new Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(),
# app/config/config.yml

    default_contexts: [cms]


            # enable the DynamicRouter with high priority to allow overwriting configured routes with content
            #cmf_routing.dynamic_router: 200
            # enable the symfony default router with a lower priority
            router.default: 100

    multisite: host
    use_streamed_response: true # set the value to false in debug mode or if the reverse proxy does not handle streamed response
        - ^(.*)admin(.*)   # ignore admin route, ie route containing 'admin'
        - ^_(.*)          # ignore symfony routes

        - sonata_page_cache_esi
        - sonata_page_cache_ssi
        - sonata_page_js_sync_cache
        - sonata_page_js_async_cache
        - sonata_cache_esi
        - sonata_cache_ssi
        - sonata_cache_js_async
        - sonata_cache_js_sync
        - sonata_cache_apc

        - ^/admin\/   # ignore admin route, ie route containing 'admin'

        homepage: {decorate: false} # disable decoration for homepage, key - is a page route

    default_template: default # template key from templates section, used as default for pages
        default: {path: 'SonataPageBundle::layout.html.twig', name: default }

    # manage the http errors
        not_found: [404]    # render 404 page with "not_found" key (name generated: _page_internal_error_{key})
        fatal:     [500]    # so you can use the same page for different http errors or specify specific page for each error

    backend: sonata.notification.backend.runtime

        - { queue: sonata_page, types: [,]}
        - { queue: catchall, default: true}

            message_manager: sonata.notification.manager.message.default
            max_age:         86400     # max age in second
            pause:           500000    # delay in microseconds
            batch_size:      10        # number of messages on each iteration
            states:                    # raising errors level
                in_progress: 10
                error:       20
                open:        100
                done:        10000

Note : The sonata_block.context_manager parameter is made to avoid the error : An exception has been thrown during the rendering of a template (“The options “manager”, “page_id” do not exist. Known options are: “attr”, “class”, “code”, “extra_cache_keys”, “layout”, “template”, “ttl”, “use_cache””) in SonataPageBundle::layout.html.twig at line 18.

Extending Page Bundle

We create our extension for Page Bundle. This mainly allows us to make change to the bundle behavior and model in a centralized maner.

app/console sonata:easy-extends:generate SonataPageBundle --dest="./src"

Then you can now update doctrine mapping :

# app/config/config.yml
                    ApplicationSonataUserBundle: ~
                    SonataUserBundle: ~
                    FOSUserBundle: ~
                    ApplicationSonataPageBundle: ~
                    SonataPageBundle: ~


Enable the page bundle extension in the Kernel :

// app/AppKernel.php
public function registerBundles()
    return array(
        // ...
        new Application\Sonata\PageBundle\ApplicationSonataPageBundle(),

Updating database

We have some more table to create in our database.

doctrine:schema:update --force

Error ! sqlite doesn’t support this command. Son we have to do

app/console doctrine:database:drop --force
app/console doctrine:schema:create
chmod 664 app/data/database.sqlite
app/console fos:user:create admin admin --super-admin

Not good ! Will see that in a next article.

Passing tests

ReReRun a :

app/console cache:clear --env=test
bin/behat --tags="sonataPage"

Green !

Next article will talk about Data Fixtures. See you.


comments powered by Disqus