TWIG templating

Je pagina's opmaken met TWIG

TWIG is een templating systeem, dat betekend dat je op een snelle en makkelijke manier een pagina kan maken waarbij je componenten (onderdelen) kan gebruiken die je kan hergebruiken. Denk bijvoorbeeld aan een bepaalde knop die je vaker gebruikt of een formulier, footer, header etc.

Het is HTML/CSS met een beetje programmeren

De basis van een TWIG file is HTML/CSS en wellicht wat JavaScript (maar bij Symfony hoort dat in de /assets/app.js bestand (bestanden).
Toch kan je er wel in programmeren, voornamelijk if-statements, for-loops, inladen van andere bestanden includes), data tonen (bijvoorbeeld productnamen) en controleren of gebruikers wel/ niet ingelogd zijn

De $this->render() functie

Vanuit MVC-model gedachte worden Views nooit direct aangeroepen maar altij via een Controller ingeladen/ gemaakt of in het Engels rendering. Daarom zie je in de Controller aan het einde van een route in een functie vaak $this->render('home.twig.html')
Een voorbeeld van een route naar de homepage (route "/") kan dan zijn:

#[Route('/', name: 'app_index')]
public function index(): Response
{
    //Return a renderd TWIG (html/css) page
    return $this->render('home/index.html.TWIG');
}

De extends functie

Vanuit de basis heb je al gezien (als het goed is) dat in de basis TWIG bestanden in Symfony altijd beginnen met de volgende regel:
{% extends 'base.html.TWIG' %}
Het eerste wat de render functie doet is het bestand ophalen en verwerken, in deze dus het bestand /templates/base.twig.html. In dit bestand vind je basis HTML/CSS om een HTML pagina te maken en daarin vind je ook TWIG blokken gemarkeerd door
{% block body %}{% endblock %}
Het woordje body is in deze code de naam van het blok.

Werken met block-code

Vanuit een controller laadt je niet direct de base.twig.html in maar altijd een ander bestand. In ons voorbeeld wordt het bestand /templates/home/index.twig.html ingeladen en in dat bestand wordt de extends functie aangeroepen. De block delen die in het base bestand staan kan je, maar dit hoeft niet, gebruiken. Het body block is waar alle basis data in staat wat je wilt tonen, het is raadzaam die te gebruiken.

{% extends 'base.html.TWIG' %}

{% block title %}Welkom!{% endblock %}

{% block body %}
    <h1>Hallo en welkom</h1>
    <p>
        Dit is mijn homepage, hier vind je leuke dingen
    </p>
{% endblock %}
Een voorbeeld van een basis TWIG bestand met de extends functie

Als je een block niet gebruikt, zal deze ook niet gevuld worden, tenzij in de base er iets in het block deel staat, dat is dan de standaard waarde die hij toont. Je kan dit bijvoorbeeld zien in de /templates/base.twig.html waar het block van de title al gevuld is met een standaard waarde.

De include functie

Naast dat je de code dus vooraf vanuit een base template kan tonen kan je stukken code ook inladen. Deze code is iets wat je vaker gebruikt of als het handig is om het apart te hebben, bijvoorbeeld een menu-navigatie. Deze code staat ook 'gewoon' in een TWIG file en wordt extra ingeladen. Deze code hoeft niet speciaal nog in een block te staan, alles wordt ingeladen.

<body>
        {% include('nav.html.twig') %}
        <div class="container">
            {% block body %}{% endblock %}
        </div>
    </body>
Een voorbeeld van een stuk code uit de base.twig.html
In het voorbeeld wordt de /templates/nav.twig.html ingeladen net boven het element met de container class. In de nav.twig.html kan je dan jouw menu bouwen.

Data doorgeven vanuit een controller

Zoals je hebt kunnen lezen roep je een TWIG file aan via een controller. Bijvoorbeeld op de app_index route of je home-pagina. In jouw controller zal dan ongeveer het volgende als minimale functie staan.

#[Route('/', name: 'app_index')]
public function index(): Response
{
    //Return a renderd TWIG (html/css) page
    return $this->render('home/index.html.TWIG');
}
Een voorbeeld van een homepage waarin de TWIG file in de map /templates/home/index.twig.html aangeroepen wordt.
Vaak zal je echter data willen sturen naar jouw pagina, bijvoorbeeld alle gebruikers of andere informatie uit jouw database of gegevens n.a.v. een ingevuld formulier etc. Dit kan je doen door een tweede argument aan de $this->render() methode mee te geven. Dit tweede argument is een array en kan een of meerdere waarden bevatten.
#[Route('/', name: 'app_index')]
public function index(): Response
{
    //Return a renderd TWIG (html/css) page
    return $this->render('home/index.html.TWIG', [
        'showText' => 'Hello World';
    ]);
}
Na de 'home/index.html.TWIG' is nu een array toegevoegd met een key-value van 'showText' en met waarde 'Hello World'

Tonen van de data in de TWIG file

In het TWIG bestand zijn variabelen gewoon uitgeschreven maar staan zij tussen twee keer twee brackets {{ }} Variabelen hebben, in tegenstelling tot PHP, geen begin $ dollar-teken.
Uit het bovenstaande voorbeeld kan je de tekst Hello World in jouw TWIG bestand dus tonen met de code {{ showText }}

Programmeren met brackets

In Symfony programmeer je door functies te starten en sluiten met {% %}. Een if-statement is bijvoorbeeld: {% if user.age > 18 %}
Als je data wilt tonen gebruik je dubbele brackets {{ user.name }}

De if-statement

Hier boven zag je al een stuk code van een if-statement. Je kan natuurlijk deze uitbreiden met else-if en else.

{% if user.age > 18 %}
    <div>Je bent boven de 18!</div>
{% else %}
    <div>Je bent boven de 18!</div>
{% endif %}
{% if user.age > 18 %}
    <div>Je bent boven de 18!</div>
{% elseif user.age > 16 %}
    <div>Je bent boven de 16!</div>
{% else %}
    <div>Je bent nog geen 16</div>
{% endif %}

De FOR-loop

Een andere veel gebruikte functie is de for-loop. Let op dat in tegenstelling tot JavaScript of PHP de for-loop. Het eerste woord is de waarde die je gebruikt uit de lijst en het tweede woord is de lijst (array/ object).
In het onderstaande voorbeeld sturen we de variabele categories mee vanuit de controller en tonen we de naam van alle categorieen in een for-loop

{% for cat in categories %}
    <div>Categorie - {{ cat.name }}</div>
{% endfor %}
Je kan ook, net als in een PHP for-loop het index getal gebruiken.
{% for key, cat in categories %}
    <div>Categorie nummer {{ key }} heeft de naam {{ cat.name }}</div>
{% endfor %}

Speciale TWIG functies

Je kan de naam van een route ophalen met het path() commando.
{{ path('app_index') }}

Je kan een asset ophalen met het asset() commando.
{{ asset('/img/my-image.png') }}
LET OP: Het bestand wat je hier aanroept moet in de /assets/img/ map staan.
Symfony maakt er vervolgens een gecached bestand van, zodat als het wijzigd de naam ook wijzigd.

Je kan controleren of er een ingelogde gebruiker is door een check te doen op app.user

{% if app.user %}
    //Doe als gebruiker ingelogd is, bijvoorbeeld naam tonen in het menu
{% else %}
    //Doe als gebruiker NIET ingelogd is, bijvoorbeeld inlog-route tonen
{% endif %}

Meer informatie?

Er kan nog veel meer met TWIG, als je dit wilt weten kan je het beste de TWIG documentatie raadplegen OF Google gebruiken.
Klik hier voor de TWIG documentatie site