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 %}