Back to symfony.com

Lesson 4 of 11 · 4 min

Click any paragraph or press to highlight its code

Twig templates

The render() helper renders a template and wraps the result in a Response object. The second argument is the list of variables the template can use.

Templates are written in Twig, a template language designed to be concise, safe (output is escaped by default) and friendly for designers. {{ ... }} prints a value, and filters like |title transform it.

{% ... %} runs logic, like looping over the speakers array passed by the controller.

The true Twig superpower: inheritance. Write the shared elements (e.g. the header and footer) once in a base.html.twig template, and let other templates extend it and fill in only the content blocks that change on each page.

<?phpnamespace App\Controller;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Attribute\Route;class ConferenceController extends AbstractController{    #[Route('/conference/{slug}')]    public function show(string $slug): Response    {        return $this->render('conference/show.html.twig', [            'conference' => $slug,            'speakers' => ['Fabien', 'Nicolas', 'Javier'],        ]);    }}
{% extends 'base.html.twig' %}{% block title %}{{ conference|title }} Conference{% endblock %}{% block body %}    <h1>Welcome to {{ conference|title }}!</h1>    <ul>        {% for speaker in speakers %}            <li>{{ speaker }}</li>        {% endfor %}    </ul>{% endblock %}