Do you think you know Sonata? Guide to the set of bundles for Symfony2

What is Sonata?

Sonata is the open source set of bundles that allows to create a dynamic administrative panel in no time. All Sonata requires from the developer is the creation of the Admin class and defining three methods that are responsible for generating the creation form, editing objects and selection of fields used for presenting the list of objects (in the form of the table or grid). This class extends the Admin type. The result is a complex and esthetic dashboard that allows to manage the content of the database with ease.

How Sonata works?

The main element of Sonata is SonataAdminBundle. It includes the class Sonata\AdminBundle\Admin\Admin which allows to create administrative panels for entities used in the project. For given entity:

// src/AppBundle/Entity/Category.php
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Entity
*/
class Category
{
/*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

public function getId()
{
return $this->id;
}

/**
* @ORM\Column(type="string", length=32, unique=true)
*/
protected $name;

public function getName()
{
return $this->name;
}

public function setName($name)
{
$this->name = $name;
}
}

The Admin class may look like that:

// src/AppBundle/Admin/CategoryAdmin.php
namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;

class CategoryAdmin extends Admin
{
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('name', 'text');
}

protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper->add('name');
}

protected function configureListFields(ListMapper $listMapper)
{
$listMapper->addIdentifier('name');
}
}

In order to add the section intended for editing categories to the dashboard, the registration of the aforementioned class as a service is needed:

# app/config/services.yml

services:
admin.category:
class: AppBundle\Admin\CategoryAdmin
arguments: [~, AppBundle\Entity\Category, ~]
tags:
- { name: sonata.admin, manager_type: orm, label: Category }

Main and most useful functions

Not only does Sonata generate the administrative panel automatically, but also provides developers with elements ready to be used in their application.

  • ClassificationBundle - stores ready to use category, collection and tag entities which enable classifying objects for later filtering. Additionally, this function allows to use contexts which, for instance, divide tags into these used for news and images.
  • MediaBundle – enables uploading files to the server (especially images) and their management. Every file is treated as a single entity and may be used by any other entity. Four types of data is enabled by default – Dailymotion and Youtube movies, images and documents. It’s possible to define handling other types of files or your own media provider. One of its advantages is the integration with Amazon S3 cloud and LiipImagineBundle (images’ transformations).
  • NewsBundle – used mainly for creating news, but it can also be used successfully as a base for a blog. Posts and comments entities with respective administrative panels defined for them are included. Posts can be published at defined date and time, they can be hidden (without removing them) and adjusted in terms of comments configuration (separately for each post).
  • UserBundle – extends popular FOSUserBundle with the possibilities of adding, editing and deleting users from the panel’s level, enriches user’s entity with many frequently used fields, adds new templates and styles and gives the possibility of implementing a two-step user’s authentication
  • TranslationBundle - Useful in creating multilanguage applications; based on commonly used extension of Doctrine2: Gedmo Translatable, adds the option of switching language versions in the objects’ edition form
  • SeoBundle – useful for metatags management. Provides Twig with extensions used for metadata rendering. Tags can be defined for the whole application as well as for a single entity. Additionally, tags can be defined in the controller's action if necessary.

How does Sonata improve the efficiency of work?

  • Generating the set of tools for editing of entities requires extending only one class and registering this class as a service – the amount of work is minimal, especially that tools for automatic generation of Admins exist.
  • Adding, editing or deleting fields of entities requires modifications only in the fields of the form responsible for creating/editing the object and in fields’ lists displayed in the table of all objects
  • Additional bundles provide out of the box solutions that are ready to use right after the installation. Moreover, it’s possible to link them togrther. For instance, news can be joined with categories which are connected to icons.
  • Sonata is continuously updated thanks to the huge support of the community - any bugs that are found are quickly fixed.

Installation - how to start working with Sonata

Sonata can be installed – similarly to Symfony – via Composer. Dependencies presented below are required for Sonata (AdminBundle + UserBundle + ClassificationBundle + MediaBundle + NewsBundle + TranslationBundle + SeoBundle) to be installed (tested with Symfony 2.8.7):

composer require sonata-project/admin-bundle "^3.3" --no-update
composer require sonata-project/block-bundle "^3.0" --no-update
composer require sonata-project/cache-bundle "^2.2" --no-update
composer require sonata-project/classification-bundle "^3.0" --no-update
composer require sonata-project/core-bundle "^3.0" --no-update
composer require sonata-project/doctrine-orm-admin-bundle "^3.0" --no-update
composer require sonata-project/easy-extends-bundle "^2.1" --no-update
composer require sonata-project/formatter-bundle "^3.0" --no-update
composer require sonata-project/intl-bundle "^2.2" --no-update
composer require sonata-project/media-bundle "^3.0" --no-update
composer require sonata-project/news-bundle "^3.0" --no-update
composer require sonata-project/notification-bundle "^3.0" --no-update
composer require sonata-project/seo-bundle "^2.0" --no-update
composer require sonata-project/translation-bundle "^2.0" --no-update
composer require sonata-project/user-bundle "^3.0" --no-update
composer update -o

Installed bundles have to be registered in the AppKernel.php:

public function registerBundles()
{
$bundles = array(
// ...
new Ivory\CKEditorBundle\IvoryCKEditorBundle(),
new Knp\Bundle\MenuBundle\KnpMenuBundle(),
new Knp\Bundle\MarkdownBundle\KnpMarkdownBundle(),

new Sonata\AdminBundle\SonataAdminBundle(),
new Sonata\BlockBundle\SonataBlockBundle(),
new Sonata\ClassificationBundle\SonataClassificationBundle(),
new Sonata\CoreBundle\SonataCoreBundle(),
new Sonata\DatagridBundle\SonataDatagridBundle(),
new Sonata\DoctrineORMAdminBundle\SonataDoctrineORMAdminBundle(),
new Sonata\EasyExtendsBundle\SonataEasyExtendsBundle(),
new Sonata\FormatterBundle\SonataFormatterBundle(),
new Sonata\MediaBundle\SonataMediaBundle(),
new Sonata\NewsBundle\SonataNewsBundle(),
new Sonata\SeoBundle\SonataSeoBundle(),
new Sonata\TranslationBundle\SonataTranslationBundle(),
new FOS\UserBundle\FOSUserBundle(),
new Sonata\UserBundle\SonataUserBundle('FOSUserBundle'),
);
// ...
}

In the next step we have to take care of configuring and extending few packages. The detailed instruction on how to do it is available online on the official website in the documentation section. I’ll will only mention about extending packages, because one of the bundles – EasyExtendsBundle – is responsible for it. It adds a console command which allows to create bundle that can inherit anything from any other bundle. Additionally, it generates automatically the structure of the folders and files (entities, controllers, templates) for these elements that were selected as worth extending by the author of the package and therefore follow the convention.

For instance, SonataMediaBundle can be extended simply by typing that line in the command prompt:

php app/console sonata:easy-extends:generate --dest=src SonataMediaBundle

As a result, a new bundle will be generated (ApplicationSonataMediaBundle) which has media and gallery entities ready to be extended and which inherits from the original SonataMediaBundle. You can find more information about the inheritance in official Symfony documentation.

What is especially worth to take a look at

Apart from obvious advantages Sonata has some flaws. Here are a few tips which may save you some time and prevent a headache.

  • Some Sonata packages tend to generate conflicts in Composer when the dev-master is not used. It can cause potential problems with the stability of the library.
  • The documentation isn’t top-shelf – during the first installation of Sonata I recommend installing components separately, while reading the instruction from cover to cover and regularly checking if everything works as intended. Saving an empty but configured project is a good idea as well – you don’t have to start from scratch.
  • Sonata is very good at generating CRUDs, but unfortunately there are no ready solutions designed for managing single elements of the application. For instance if you want to add the editable content on the main page, the simplest way is to create a separate table for storing only one record with saved settings. Additionally, possibility of adding and removing records should be disabled.
  • Automatically generated panel has one flaw – it isn’t optimized for handling database queries. In extreme cases the amount of queries for a single HTTP request may reach even hundreds. Limiting the number of queries requires the manual configuration of Sonata in the way it uses queries written by the developer or the entities’ adjustment in order to modify the method associations are retrieved from LAZY to EAGER.

Summary

Python has Django, Ruby on Rails uses ActiveAdmin, and Symfony uses Sonata. It’s currently the best tool for creating the administrative panel for the application based on this framework – thanks to that the community is using Sonata daily and that guarantees the steady development of the project. Despite some problems regarding the very mediocre documentation at best and the high threshold directly associated with it, I believe it’s worth to give Sonata a chance – since I started using it, my every project is Sonata-based and I don’t regret it.

Navigate the changing IT landscape

Some highlighted content that we want to draw attention to to link to our other resources. It usually contains a link .