Laisser Twig faire le dur travail

Dans le tutoriel précédent, nous avons créé (techniquement: généré) notre première classe de contrôleur, avec une méthode de contrôleur unique qui restituait et index.html.twig notre modèle index.html.twig .

En gardant les choses simples, nous mettons tout dans le templates/welcome/index.html.twig . Ce faisant, nous avons créé une belle page web pour la racine de notre site ( / ), mais en visitant notre autre route ( /hello ), nous avons vu une page basique, sans style.

Ce que nous ne voulons pas faire est de copier / coller l'ensemble de la mise en page et de la barre de navigation d'un modèle à l'autre, chaque fois que nous créons un nouveau modèle ou que nous mettons à jour un modèle existant. Ce serait un mauvais moment.

Au lieu de cela, ce que nous allons faire est d'extraire ces parties communes de notre mise en page, puis créer des blocs que nous pouvons remplir sur une base par page. C'est beaucoup plus facile à voir en pratique, alors allons-y tout de suite.

Tout sur la base

Une chose que je n'ai pas mentionnée dans la vidéo précédente, mais que symfony/website-skeleton nous donne gratuitement est la templates/base.html.twig .

C'est un template vraiment simple:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        {% block stylesheets %}{% endblock %}
    </head>
    <body>
        {% block body %}{% endblock %}
        {% block javascripts %}{% endblock %}
    </body>
</html>

Il est difficile de manquer tous ces tags de block .

Un block nous permet de définir les zones qui peuvent être modifiées.

En prenant le block title du block title comme exemple, nous souhaitons probablement définir un tag de titre de page unique pour chacune des pages de notre site. Nous pouvons le faire en définissant une nouvelle balise {% block title %}...{% endblock %} dans tout modèle qui extends ce modèle de base.

Notez également que le block title du block title ci-dessus contient du texte déjà défini dans les balises de block . Si aucune balise de block title n'est définie dans un modèle enfant, la valeur par défaut, Welcome! sera utilisé.

Vous pouvez en lire plus à ce sujet ici .

templates/base.html.twig le code HTML courant de notre templates/welcome/index.html.twig et placez-le dans le fichier template templates/base.html.twig :

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>{% block title %}Let's Explore Symfony 4{% endblock %}</title>

    <!-- Bootstrap core CSS -->
    <link rel="stylesheet"
          href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css"
          integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy"
          crossorigin="anonymous">
    <link rel="stylesheet" href="{{ asset('css/custom-style.css') }}" />
    {% block stylesheets %}{% endblock %}
</head>

<body>

<header>
    <nav class="navbar navbar-expand-sm navbar-dark bg-dark">
        <div class="container">

            <a class="navbar-brand" href="{{ path('welcome') }}">Home</a>

            <div class="collapse navbar-collapse">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="{{ path('hello_page') }}">Hello Page</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</header>

<main role="main" class="container main">
    {% block body %}{% endblock %}
</main>

{% block javascripts %}{% endblock %}
</body>
</html>

Il s'avère que la plupart de notre modèle était générique.

Nous pourrons ajouter le texte h1 et "lorum ipsum" via la balise block body de notre template welcome/index.html.twig .

En ce moment, si nous actualisons la page dans notre navigateur Web, rien n'a changé.

Symfony n'est pas un lecteur d'esprit. Pas encore en tout cas. Peut-être dans Symfony 5, quand ils implémentent la logique de terminaison avancée de la série T-1000.

Nous devons dire à notre welcome/index.html.twig d' extends le template base.html.twig .

Cela signifie également que nous devons mettre à jour le modèle welcome/index.html.twig pour supprimer tous les éléments que nous venons d'extraire.

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

{% block body %}
    <div>
        <h1>Let's Explore Symfony 4</h1>
        <p class="lead">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras rutrum sapien mauris, venenatis
            facilisis neque tincidunt vel. Maecenas vel felis vel turpis scelerisque eleifend. Fusce nec purus egestas,
            efficitur nisi ac, ultrices nulla. Pellentesque eu mollis tortor, in mollis nisl. Maecenas rhoncus quam non
            lacinia mollis.</p>
    </div>
{% endblock %}

Tout ce qui est à l'intérieur de l'étiquette de block body est maintenant affiché à l'intérieur de la zone de block body définie dans le modèle que nous extends .

Si vous avez mal orthographié le nom du bloc exact, votre texte ne s'affichera tout simplement pas. Le reste du modèle sera toujours rendu, et tous les blocs correctement nommés apparaîtront. C'est une erreur facile à faire, et peut être déroutant de traquer. Cela peut ne pas sembler si problématique étant donné que nous n'avons actuellement que quatre block , mais sur des structures de site plus grandes, c'est plus facile à faire.

Une meilleure page de bonjour

Tout ce qui précède serait beaucoup de travail si tout ce que nous avions était un site Web avec une page.

Heureusement, nous en avons deux.

Et maintenant que nous avons fait tout le «dur travail» pour configurer la mise en page de notre site, nous pouvons en profiter pleinement en changeant les templates/hello_page.html.twig et en obtenant immédiatement les beaux styles et la barre de navigation, et une page par défaut title , et ainsi de suite:

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

{% block body %}
    Hello, Sehbani Redouane!
{% endblock %}

Aussi simple que cela, nous avons les deux pages sous une mise en page centralisée.

Nous pouvons donner à ce hello_page un title personnalisé en changeant le block title du block title :

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

{% block title %}Some custom title{% endblock title %}

{% block body %}
    Hello, CodeReviewVideos!
{% endblock %}

Et lors de l'actualisation de la page, nous voyons notre nouveau titre de page.

Remarquez comment j'ai utilisé le endblock title bloc, mais pour le bloc de body , je viens d'utiliser endblock ?

Les deux syntaxes sont valides. Typiquement, je préfère juste le bloc endblock , mais donner le nom de bloc spécifique dans la balise de fermeture de bloc endblock peut être utile pour faire correspondre des balises sur des modèles plus impliqués.

L'ordre du block n'a pas d'importance.

{% block body %}
    Hello, Sehbani Redouane!
{% endblock %}

{% block title %}Some custom title{% endblock title %}

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

Même si tout est "à l'envers", votre page s'affichera correctement. Ma préférence est de garder les étiquettes dans l'ordre où elles apparaissent dans le parent, pour plus de simplicité.

Quelle est l' app ?

En tête à tête: vous pouvez passer cette section entière et passer à la vidéo suivante si vous ne souhaitez pas augmenter vos compétences de geek Symfony. Ce que nous apprenons ici est bon à savoir, mais pas essentiel.

Toujours là? Cool. Rendons notre "Hello Page" un peu plus intéressant.

Plutôt que de coder en dur pour "Bonjour, CodeReviewVideos!", Ne serait-il pas plus agréable de transmettre une valeur au moment de l'exécution?

Disons plutôt que d'accéder simplement à http://127.0.0.1:8000/hello , nous pourrions plutôt accéder à http://127.0.0.1:8000/hello?name=Chris et afficher "Hello, Chris!".

Étant donné que nous n'utilisons pas une classe de contrôleur ou une méthode de contrôleur personnalisée, il semble que cela puisse être difficile à résoudre.

Cependant, Twig reçoit implicitement une variable d' app . Et cette variable d' app nous donne accès à un tas de choses intéressantes, telles que l'utilisateur actuel ( app.user ), l'environnement par exemple 'prod', 'dev' ( app.environment ), la demande actuelle (demande d' app.request ) et quelques autres .

Ceci n'est pas immédiatement évident. Mais vous pouvez le constater par vous-même en utilisant une autre fonction pratique de Twig: dump :

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

{% block title %}Some custom title{% endblock title %}

{% block body %}

    {{ dump() }}

    Hello, Sehbani redouane!
{% endblock %}

Maintenant actualisez la page et vous verrez une représentation de tableau déversée à l'écran contenant toutes les variables passées pour ce render . Dans notre cas, nous avons seulement cette variable d' app implicite, mais nous verrons bientôt plus ici.

Cela montre des choses plus avancées que ce dont vous auriez peut-être besoin, mais j'aime bien "décoller" les rideaux et donner un aperçu de ce qui se passe, même si vous ne comprenez pas complètement (ou même partiellement) il.

Comme mentionné ci-dessus, si nous pouvons avoir accès à la requête en cours (demande d' app.request ), nous pouvons avoir accès aux paramètres de requête pour cette requête. Les paramètres de requête sont ceux que vous voyez dans une URL après le point d'interrogation.

Si nous naviguons vers notre page sur http://127.0.0.1:8000/hello?name=Chris , alors développez la sortie de dump pour:

app > requestStack > request > 0 > query > parameters

Ensuite, vous devriez être en mesure de voir tout paramètre de requête de name que vous définissez:

sortie de vidage symfony 4 twig

Utilisons ceci dans notre template.

 {% extends 'base.html.twig' %} {% block title %}Some custom title{% endblock title %} {% block body %} Hello, {{ app.request.query.get('name') }}! {% endblock %} 

Et cool, nous voyons "Bonjour, Chris!" (ou tout ce que vous avez défini), tout enveloppé joliment dans nos styles Bootstrap de fantaisie.

Il y a un inconvénient ici.

Et si nous devenons voyous et envoyer une demande à: http://127.0.0.1:8000/hello

Ou, nous obtenons gros doigt et mal orthographier notre paramètre de requête: http://127.0.0.1:8000/hello?nom=bob

Ensuite, nous voyons le moins attrayant: "Bonjour,!"

Oh mon.

Eh bien, heureusement, Twig a toujours nos dos ici.

Nous pouvons définir un default :

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

{% block title %}Some custom title{% endblock title %}

{% block body %}

    Hello, {{ app.request.query.get('name') }}!

{% endblock %}

Maintenant, si le paramètre de la requête n'est pas défini, ou mal orthographié, ou quoi que ce soit, nous revenons à une belle valeur par défaut: "Bonjour, Sehbani redouane!"

C'est bon, non?

Bon type de.

Je ne ferais pas ça dans le monde réel.

Je vous montre ceci parce que savoir que vous pouvez faire ceci est utile.

Mais la plupart du temps, la grande majorité du temps dans mon cas, vous êtes beaucoup plus susceptible de vouloir / besoin de passer des variables à partir de vos méthodes de contrôleur. Alors, faisons cela dans le tutoriel suivant .