Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. What is Symfony
  3. Quick Tour
  4. The View
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • Getting familiar with Twig
  • Decorating Templates
  • Using Tags, Filters, and Functions
    • Including other Templates
    • Embedding other Controllers
    • Creating Links between Pages
    • Including Assets: images, JavaScripts, and stylesheets
  • Escaping Variables
  • Final Thoughts

The View

Edit this page

Warning: You are browsing the documentation for Symfony 2.0, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

The View

After reading the first part of this tutorial, you have decided that Symfony2 was worth another 10 minutes. Great choice! In this second part, you will learn more about the Symfony2 template engine, Twig. Twig is a flexible, fast, and secure template engine for PHP. It makes your templates more readable and concise; it also makes them more friendly for web designers.

Note

Instead of Twig, you can also use PHP for your templates. Both template engines are supported by Symfony2.

Getting familiar with Twig

Tip

If you want to learn Twig, it's highly recommended you read its official documentation. This section is just a quick overview of the main concepts.

A Twig template is a text file that can generate any type of content (HTML, XML, CSV, LaTeX, ...). Twig defines two kinds of delimiters:

  • {{ ... }}: Prints a variable or the result of an expression;
  • {% ... %}: Controls the logic of the template; it is used to execute for loops and if statements, for example.

Below is a minimal template that illustrates a few basics, using two variables page_title and navigation, which would be passed into the template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
    <head>
        <title>My Webpage</title>
    </head>
    <body>
        <h1>{{ page_title }}</h1>

        <ul id="navigation">
            {% for item in navigation %}
                <li><a href="{{ item.href }}">{{ item.caption }}</a></li>
            {% endfor %}
        </ul>
    </body>
</html>

Tip

Comments can be included inside templates using the {# ... #} delimiter.

To render a template in Symfony, use the render method from within a controller and pass it any variables needed in the template:

1
2
3
$this->render('AcmeDemoBundle:Demo:hello.html.twig', array(
    'name' => $name,
));

Variables passed to a template can be strings, arrays, or even objects. Twig abstracts the difference between them and lets you access "attributes" of a variable with the dot (.) notation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{# array('name' => 'Fabien') #}
{{ name }}

{# array('user' => array('name' => 'Fabien')) #}
{{ user.name }}

{# force array lookup #}
{{ user['name'] }}

{# array('user' => new User('Fabien')) #}
{{ user.name }}
{{ user.getName }}

{# force method name lookup #}
{{ user.name() }}
{{ user.getName() }}

{# pass arguments to a method #}
{{ user.date('Y-m-d') }}

Note

It's important to know that the curly braces are not part of the variable but the print statement. If you access variables inside tags don't put the braces around.

Decorating Templates

More often than not, templates in a project share common elements, like the well-known header and footer. In Symfony2, you think about this problem differently: a template can be decorated by another one. This works exactly the same as PHP classes: template inheritance allows you to build a base "layout" template that contains all the common elements of your site and defines "blocks" that child templates can override.

The hello.html.twig template inherits from layout.html.twig, thanks to the extends tag:

1
2
3
4
5
6
7
8
{# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #}
{% extends "AcmeDemoBundle::layout.html.twig" %}

{% block title "Hello " ~ name %}

{% block content %}
    <h1>Hello {{ name }}!</h1>
{% endblock %}

The AcmeDemoBundle::layout.html.twig notation sounds familiar, doesn't it? It is the same notation used to reference a regular template. The :: part simply means that the controller element is empty, so the corresponding file is directly stored under the Resources/views/ directory.

Now, let's have a look at a simplified layout.html.twig:

1
2
3
4
5
{# src/Acme/DemoBundle/Resources/views/layout.html.twig #}
<div class="symfony-content">
    {% block content %}
    {% endblock %}
</div>

The {% block %} tags define blocks that child templates can fill in. All the block tag does is to tell the template engine that a child template may override those portions of the template.

In this example, the hello.html.twig template overrides the content block, meaning that the "Hello Fabien" text is rendered inside the div.symfony-content element.

Using Tags, Filters, and Functions

One of the best feature of Twig is its extensibility via tags, filters, and functions. Symfony2 comes bundled with many of these built-in to ease the work of the template designer.

Including other Templates

The best way to share a snippet of code between several distinct templates is to create a new template that can then be included from other templates.

Create an embedded.html.twig template:

1
2
{# src/Acme/DemoBundle/Resources/views/Demo/embedded.html.twig #}
Hello {{ name }}

And change the index.html.twig template to include it:

1
2
3
4
5
6
7
{# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #}
{% extends "AcmeDemoBundle::layout.html.twig" %}

{# override the body block from embedded.html.twig #}
{% block content %}
    {% include "AcmeDemoBundle:Demo:embedded.html.twig" %}
{% endblock %}

Embedding other Controllers

And what if you want to embed the result of another controller in a template? That's very useful when working with Ajax, or when the embedded template needs some variable not available in the main template.

Suppose you've created a fancyAction controller method, and you want to "render" it inside the index template. First, create a route to your new controller in one of your application's routing configuration files.

  • YAML
  • XML
  • PHP
1
2
3
4
# app/config/routing.yml
fancy:
    pattern:   /included/fancy/{name}/{color}
    defaults:  { _controller: AcmeDemoBundle:Demo:fancy }
1
2
3
4
5
6
7
8
9
10
<!-- app/config/routing.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">

    <route id="fancy" pattern="/included/fancy/{name}/{color}">
        <default key="_controller">AcmeDemoBundle:Demo:fancy</default>
    </route>
</routes>
1
2
3
4
5
6
7
8
9
10
// app/config/routing.php
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;

$collection = new RouteCollection();
$collection->add('fancy', new Route('/included/fancy/{name}/{color}', array(
    '_controller' => 'AcmeDemoBundle:Demo:fancy',
)));

return $collection;

To include the result (e.g. HTML) of the controller, use the render tag:

1
2
{# src/Acme/DemoBundle/Resources/views/Demo/index.html.twig #}
{% render url('fancy', { 'name': name, 'color': 'green'}) %}

Note

Since Symfony 2.0.20/2.1.5, the Twig render tag now takes an absolute url instead of a controller logical path. This fixes an important security issue (CVE-2012-6431) reported on the official blog. If your application uses an older version of Symfony or still uses the previous render tag syntax, you should upgrade as soon as possible.

The render tag will execute the AcmeDemoBundle:Demo:fancy controller and include its result. For example, your new fancyAction might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Acme/DemoBundle/Controller/DemoController.php

class DemoController extends Controller
{
    public function fancyAction($name, $color)
    {
        // create some object, based on the $color variable
        $object = ...;

        return $this->render('AcmeDemoBundle:Demo:fancy.html.twig', array(
            'name' => $name,
            'object' => $object
        ));
    }

    // ...
}

Creating Links between Pages

Speaking of web applications, creating links between pages is a must. Instead of hardcoding URLs in templates, the path function knows how to generate URLs based on the routing configuration. That way, all your URLs can be easily updated by just changing the configuration:

1
<a href="{{ path('_demo_hello', { 'name': 'Thomas' }) }}">Greet Thomas!</a>

The path function takes the route name and an array of parameters as arguments. The route name is the main key under which routes are referenced and the parameters are the values of the placeholders defined in the route pattern:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Acme/DemoBundle/Controller/DemoController.php
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

// ...

/**
 * @Route("/hello/{name}", name="_demo_hello")
 * @Template()
 */
public function helloAction($name)
{
    return array('name' => $name);
}

Tip

The url function generates absolute URLs: {{ url('_demo_hello', { 'name': 'Thomas'}) }}.

Including Assets: images, JavaScripts, and stylesheets

What would the Internet be without images, JavaScripts, and stylesheets? Symfony2 provides the asset function to deal with them easily:

1
2
3
<link href="{{ asset('css/blog.css') }}" rel="stylesheet" type="text/css" />

<img src="{{ asset('images/logo.png') }}" />

The asset function's main purpose is to make your application more portable. Thanks to this function, you can move the application root directory anywhere under your web root directory without changing anything in your template's code.

Escaping Variables

Twig is configured to automatically escape all output by default. Read Twig documentation to learn more about output escaping and the Escaper extension.

Final Thoughts

Twig is simple yet powerful. Thanks to layouts, blocks, templates and action inclusions, it is very easy to organize your templates in a logical and extensible way. However, if you're not comfortable with Twig, you can always use PHP templates inside Symfony without any issues.

You have only been working with Symfony2 for about 20 minutes, but you can already do pretty amazing stuff with it. That's the power of Symfony2. Learning the basics is easy, and you will soon learn that this simplicity is hidden under a very flexible architecture.

But I'm getting ahead of myself. First, you need to learn more about the controller and that's exactly the topic of the next part of this tutorial. Ready for another 10 minutes with Symfony2?

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Take the exam at home

    Take the exam at home

    Measure & Improve Symfony Code Performance

    Measure & Improve Symfony Code Performance

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of Eriksen Costa, a Symfony contributor

    Thanks Eriksen Costa for being a Symfony contributor

    37 commits • 2.29K lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia