This tutorial has a new version, check it out!

Twig: For a Good time with Templates

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Unless you're building a pure API, Twig is your new best friend. Rarely do you find a library that's this much fun to use. It's also really easy, so let me just give you a quick intro.

{{ SaySomething }}, {% doSomething %}

Twig has two syntaxes: {{ }} - which is the "say something" tag - and {% %} - which is the "do something" tag. If you're printing something, you aways write {{ then a variable name, a string or any expression: Twig looks a lot like JavaScript.

But if you're writing code that won't print something - like an if statement a for loop, or setting a variable, you'll use {% %}.

Head over to Twig's website at twig.sensiolabs.org, click Documentation and scroll down. Ah, this is a list of everything Twig does.

Look at the Tags column first: this is the short list of all "do something" tags. Click on if to see some usage. Do something tags are always {% and then if or set or one of these "tags". The for tag - used as {% for %} is for looping. You'll probably end up only using 5 or 6 of these commonly.

Twig also has other things like functions... which are exactly like functions in every language ever. Filters are a bit more interesting: check out lower. Really, these are functions, but with a trendier syntax: just print something, then use the pipe (|) to pass that value into a filter. You can have filter after filter. And, you can create your own.

The dump() Function

Let's make some magic happen in our Twig template. Our Aquanauts will take notes about each genus, and those will render on this page. Create a cool $notes variable with some hardcoded text and pass it into our Twig template:

... lines 1 - 8
class GenusController extends Controller
{
... lines 11 - 13
public function showAction($genusName)
{
$notes = [
'Octopus asked me a riddle, outsmarted me',
'I counted 8 legs... as they wrapped around me',
'Inked!'
];
return $this->render('genus/show.html.twig', array(
'name' => $genusName,
'notes' => $notes
));
}
}

But before we loop over this, I want to show you a small piece of awesome: the dump() function:

... lines 1 - 2
{{ dump() }}

This is like var_dump() in PHP, but better, and you can use it without any arguments to print details about every available variable.

Refresh the browser! There's the name variable, notes and a bonus: app - a global variable that Symfony adds to every template. More on that in the future. With the dump() function, you can expand the variables in really cool ways. Oh, and bonus time: you can also use dump() in PHP code: Symfony gives us that function.

Go Deeper!

See more usage examples of the dump() function in The dump Function for Debugging of the separate Twig screencast. chapter.

The for Tag

To print out the notes, add a <ul> and open up a for tag with {% for note in notes %}. Close it with an {% endfor %} tag. Now, it's simple: print out each note, which is a string:

... lines 1 - 2
<ul>
{% for note in notes %}
<li>{{ note }}</li>
{% endfor %}
</ul>

Back to the browser to see what we've got. Refresh! Well, it's not pretty yet, but it is working. Open the source: it's still just this html, there's no HTML layout. Time to fix that.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*", // v3.1.4
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.4
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.3.11
        "symfony/monolog-bundle": "^2.8", // 2.11.1
        "symfony/polyfill-apcu": "^1.0", // v1.2.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
        "incenteev/composer-parameter-handler": "^2.0" // v2.1.2
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.0.7
        "symfony/phpunit-bridge": "^3.0" // v3.1.3
    }
}