When you look into PHP, you may notice that over the last years the language has evolved, more mature concepts and design patterns have been created, and the approach to create the output has also changed drastically. Symfony2 as a modern framework tries to give you modern tools to make frontend development easier. In this artilce, we will cover the following topics:

  • The Twig templating engine
  • Assets management
  • Installing the frontend library
  • Adding advanced fixtures

The Twig templating engine

When Symfony1 was created, the framework did not use any of existing template systems but relied on just the PHP as a template language. It had some advantages (that is, templates did not require any processing and were very fast), but wasn’t too friendly for frontend developers. Also, PHP is a very verbose language and you need to write a lot of code to do some basic stuff such as checking a variable and determining whether it exists or is empty. Also, escaping variables requires some coding.

In Symfony2, a new templating engine, called Twig, was introduced. Twig was written with a few concepts in mind, such as:

  • Templating system is extensible: Developer may write their own extensions to it very easily.
  • Fast: The written template is compiled and processed, generating an optimized PHP code on the output.
  • More secure: It is much easier to make code secure using Twig with features such as auto-escape or sandboxing.
  • Optimized for frontend development: The Twig syntax has been optimized to make frontend development quicker and more convenient by providing shortcuts for commonly used patterns (loops, default variable values, and so on).

As usual with Symfony2, using Twig is optional but it is recommended. While the basic framework has the support for simple PHP templating, most of the extensions available in the open source community embraced Twig, and their authors don’t bother with providing working examples without Twig.


If you want to find more information about Twig, please visit its home page at http://twig.sensiolabs.org/.

Assets management

In every large web project, you will need to use images, CSS, and JS files. Usually these files are not generated dynamically, but saved statically and served by the HTTP server, so the templating system in this case is not very useful.

Within Symfony2, there were a few different ways to help with this:

  • Managing assets from bundles by installing them on the public web/ directory
  • Generating a combined CSS/JS file through Assetic


Assetic is a tool that allows you to manipulate assets files (javascripts, css) and process them before they are served to the browser. This allows you to have your own “development” versions of your files, while serving to the browser a minified, compressed, and combined version of the files.

Assetic handles its job through filters. In the following example, see the default configuration example stored in config.yml:

# Assetic Configuration
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [ ]
    #java: /usr/bin/java
        cssrewrite: ~
        #    jar: "%kernel.root_dir%/Resources/java/compiler.jar"
        #    jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"

The default setup uses the cssrewrite filter. This filter is responsible for setting up correct relative paths when working with bundles. You can also define your own filters such as the Less and Sass compiler.

A detailed configuration of Assetic is not within the scope of this book. If you seek more information about this, see the official documentation at https://symfony.com/doc/current/cookbook/assetic/index.html.

Handling third-party bundle assets

When you install a third-party bundle, it often comes with its own CSS, JS, or other files such as fonts and images. Within Symfony2, you can “install” such files on the public directory by issuing the following command:

$ php app/console assets:install –symlink      `  

This command will try to create symlink or copy assets to the web/bundles directory. After this, our assets will be available under a normalized bundle name within the web/bundles directory. The normalized name contains only lowercase letters and does not contain the word “bundle”. So for example, AcmeDemoBundle will be converted to acmedemo.


The --symlink option is useful on the *nix systems, as it creates only a symbolic link to an assets directory, which not only saves time but also sometimes makes development easier. It is not supported on Windows systems.

The same mechanism also works for your assets, which are placed in the bundle. If you create any file or directory in the src/AppBundle/Resources/public directory, it will be installed on web/bundles/app.

Handling your application assets

In your project, you will probably use a lot of JS and CSS files, which are not part of any Symfony2 bundle, such as jQuery, Bootstrap, or something else. As of Symfony 2.6, there is a recommendation to install these files directly on the web/ directory rather than using bundles. Also, it is recommended to write your own CSS/JS files here rather than putting files in various places and bundles.

Since writing tons of CSS and JavaScript is not in the scope of this book, we will use a UI component framework called semantic UI.

Go to http://1.semantic-ui.com/ and download the latest version 1 release. At the time this book was written, the current stable version of Semantic UI was 1.12.0. After you download the file, unpack it and copy the following files and directories from dist/:

themes/ -> web/css/vendor/semantic-ui/themes
semantic.min.css -> web/css/vendor/semantic-ui
semantic.min.js -> web/js/vendor/semantic-ui

Our own styles will be placed in the files that will be placed in web/css/dev/app.css and web/js/dev/app.js, so create them (they are empty for now).

After you do this, your web/css directory should contain the following:

vendor/semantic-ui/themes/ (and subdirectories)

The web/js directory should contain the following:


Now, we need to configure our project to handle these files, and we need to link these files to our page. Unless you are using some fancy frontend tool, such as Grunt, you may use Assetic to do the job.

Before we show how to use this, first we need to create a new controller to handle the tasks list. We will start by creating a new template. Create a new directory and file under app/Resources/views/task/list.html.twig with the following content:

{% extends '::base.html.twig' %}

{% block body %}
    <h2 class="ui aligned header">Your tasks list</h2>
    <p class="ui aligned">
        Below you will find your unfinished tasks
{% endblock %}

The preceding code will be displayed on our homepage. Now we need to create a new controller and routing entry. Add the following code:


// file: src/AppBundle/Controller/TaskController.php
namespace AppBundleController;

use SymfonyBundleFrameworkBundleControllerController;
use SymfonyComponentHttpFoundationRequest;

class TaskController extends Controller
    public function listAction(Request $request)
        return $this->render('task/list.html.twig');

Now modify the src/AppBundle/Resources/config/routing.yml file by replacing its content with the following:

    path:     /
    defaults: { _controller: AppBundle:Task:list }

When you see your page at, you should see a basic browser styling as we haven’t added the style sheets yet.

Now go to app/Resources/base.html.twig and modify the blocks responsible for JS and CSS. The complete code should look as follows:

<!DOCTYPE html>
        <meta charset="UTF-8" />
        <title>{% block title %}Welcome!{% endblock %}</title>
        {% block stylesheets %}
            {%  stylesheets
                <link rel="stylesheet" href="{{%20asset_url%20}}" />
            {% endstylesheets %}
        {% endblock %}
        <link rel="icon" type="image/x-icon" href="{{%20asset('favicon.ico')%20}}" />
        {% block body %}{% endblock %}
        {% block javascripts %}
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
            {% javascripts
               <script src="{{%20asset_url%20}}"></script>
            {% endjavascripts %}
        {% endblock %}

As you may have noticed in the javascripts and stylesheets blocks, we have used Assetic commands. For both JS and CSS, it accepts a list of files as parameters and generates an output file when you issue the following command:

$ php app/console assetic:dump --env=prod

This command will generate the following two files specified by the output parameter:

Dumping all prod assets.
Debug mode is off.

… /app/../web/css/app.css
… /app/../web//js/app.js

Now when you look at your css and js directories, you will notice new combined files. This way we don’t have to include multiple css/js files but just one. Also, note the parameter within the stylesheets block containing the cssrewrite filter. This filter is responsible for rewriting relative paths within the css file to the correct location, so you don’t have to worry whether your development css file or vendor file will loose its relative path to images or fonts, as this filter will amend the paths to the correct ones.

It would be very slow if we have to execute this command with every new file change. Fortunately, the Assetic manager in the development mode will be using Symfony2 for dynamic generation of new files and will notice any changes in the included files, without a need to dump assets.


If you run a standalone server, you work in the development mode by default, so you don’t have to worry about dumping, but remember this before deploying your work on the production environment.

After you modify your main template, refresh it. You would notice a slight change in the fonts of your header and text. It now looks more polished, but still sticks to the edges of page. Modify web/css/dev/app.css, and add the following code:

body {
  padding: 25px;

Refresh your homepage. You should see the visual changes.


Assetic has a lot more options. Instead of just cssrewrite, it can help you to minimize files but it does not come with these filters built-in, so using them usually requires installing some extra tools.

Now we will remove leftovers from the previously created default controller and views. Remove the following files:


Empty all directories, and then clear the cache:

$ php app/console cache:clear