Hoe templates gebruiken in een Flask applicatie

De auteur koos ervoor om een donatie te doen aan het Vrij en Open Source Fonds als onderdeel van het Write for DOnations programma.

Inleiding

Flask is een lichtgewicht Python webframework dat nuttige tools en functies biedt voor het maken van webapplicaties in de Python taal.

Bij het ontwikkelen van een webapplicatie is het belangrijk om zakelijke logica te scheiden van presentatielogica. Zakelijke logica houdt zich bezig met het verwerken van gebruikersverzoeken en het communiceren met de database om een geschikt antwoord te bouwen. Presentatielogica gaat over hoe de gegevens aan de gebruiker worden gepresenteerd, meestal met behulp van HTML-bestanden om de basisstructuur van de antwoordwebpagina te bouwen, en CSS-stijlen om HTML-componenten te stylen. Bijvoorbeeld, in een sociaalemediatoepassing, zou je een gebruikersnaamveld en een wachtwoordveld kunnen hebben dat alleen wordt weergegeven wanneer de gebruiker niet is ingelogd. Als de gebruiker is ingelogd, toont u in plaats daarvan een uitlogknop. Dit is de presentatielogica. Als een gebruiker zijn gebruikersnaam en wachtwoord invoert, kunt u Flask gebruiken om zakelijke logica uit te voeren: U extraheert de gegevens (de gebruikersnaam en het wachtwoord) uit het verzoek, logt de gebruiker in als de inloggegevens correct zijn of antwoordt met een foutmelding. Hoe de foutmelding wordt weergegeven, wordt afgehandeld door de presentatielogica.

In Flask kun je de Jinja templating taal gebruiken om HTML templates te renderen. Een template is een bestand dat zowel vast als dynamisch inhoud kan bevatten. Wanneer een gebruiker iets aanvraagt bij je applicatie (zoals een indexpagina of een loginpagina), stelt Jinja je in staat om te reageren met een HTML template waarin je veel functies kunt gebruiken die niet beschikbaar zijn in standaard HTML, zoals variabelen, if statements, for loops, filters en template overerving. Deze functies stellen je in staat om efficiënt eenvoudig te onderhouden HTML pagina’s te schrijven. Jinja ontslaat HTML ook automatisch om Cross-Site Scripting (XSS) aanvallen te voorkomen.

In deze tutorial bouw je een kleine webapplicatie die verschillende HTML bestanden rendert. Je gebruikt variabelen om data van de server naar de templates te sturen. Template overerving helpt je herhaling te vermijden. Je gebruikt logica in templates zoals conditionals en loops, gebruikt filters om tekst te wijzigen en gebruikt het Bootstrap toolkit om je applicatie te stylen.

Vereisten

Stap 1 — Een sjabloon renderen en variabelen gebruiken

Zorg ervoor dat je je omgeving hebt geactiveerd en Flask hebt geïnstalleerd, en dan kun je beginnen met het bouwen van je applicatie. De eerste stap is om een welkomstbericht te tonen dat bezoekers verwelkomt op de indexpagina. Je zult Flask’s render_template() helperfunctie gebruiken om een HTML-sjabloon als respons te serveren. Je zult ook zien hoe je variabelen vanuit je applicatiekant naar je sjablonen kunt doorgeven.

Open eerst in je flask_app directory een bestand genaamd app.py om te bewerken. Gebruik nano of je favoriete teksteditor:

  1. nano app.py

Voeg de volgende code toe in het app.py bestand:

flask_app/app.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello():
    return render_template('index.html')

Sla het bestand op en sluit het.

In dit codeblok importeer je de Flask klasse en de render_template() functie uit het flask pakket. Je gebruikt de Flask klasse om je Flask applicatie-instantie te maken, genaamd app. Vervolgens definieer je een view functie (een Python functie die een HTTP-respons retourneert) genaamd hello() met behulp van de app.route() decorator, die een reguliere functie omzet in een view functie. Deze view functie gebruikt de render_template() functie om een sjabloonbestand genaamd index.html te renderen.

Vervolgens moet je het index.html sjabloonbestand aanmaken in een map genaamd templates binnen je flask_app map. Flask zoekt naar sjablonen in de templates map, die templates heet, dus de naam is belangrijk. Zorg ervoor dat je in de flask_app map bent en voer de volgende opdracht uit om de templates map aan te maken:

  1. mkdir templates

Open vervolgens een bestand genaamd index.html in de templates map voor bewerking. De naam index.html hier is geen standaard vereiste naam; je kunt het home.html of homepage.html of iets anders noemen als je wilt:

  1. nano templates/index.html

Voeg de volgende HTML-code toe in het index.html bestand:

flask_app/templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
</head>
<body>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
</body>
</html>

Hier stel je een titel in, voeg je een Hello World! bericht toe als een H1 kop en maak je een Welcome to FlaskApp! bericht aan als een H2 kop.

Sla het bestand op en sluit het.

Terwijl je in je flask_app map bent met je virtuele omgeving geactiveerd, geef je Flask door wat de applicatie is (app.py in jouw geval) met behulp van de FLASK_APP omgevingsvariabele, en stel je de FLASK_ENV omgevingsvariabele in op development om de applicatie in ontwikkelingsmodus te runnen en toegang te krijgen tot de debugger. Gebruik de volgende commando’s om dit te doen (op Windows, gebruik set in plaats van export):

  1. export FLASK_APP=app
  2. export FLASK_ENV=development

Voer vervolgens de applicatie uit met het flask run commando:

  1. flask run

Met de ontwikkelingsserver draaiend, bezoek de volgende URL met je browser:

http://127.0.0.1:5000/

Je zult zien dat de titel van de pagina is ingesteld op FlaskApp, en de twee koppen zijn weergegeven HTML.

In webapplicaties moet je vaak gegevens doorgeven vanuit de Python-bestanden van je applicatie naar je HTML-sjablonen. Om te demonstreren hoe je dit kunt doen in deze applicatie, zul je een variabele doorgeven die de huidige UTC-datum en -tijd bevat naar het indexsjabloon, en je zult de waarde van de variabele weergeven in het sjabloon.

Laat de server draaien en open je app.py-bestand voor bewerken in een nieuwe terminal:

  1. nano app.py

Importeer de datetime module uit de Python standaardbibliotheek en bewerk de index() functie zodat het bestand er als volgt uitziet:

flask_app/app.py
import datetime
from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def hello():
    return render_template('index.html', utc_dt=datetime.datetime.utcnow())

Bewaar en sluit het bestand.

Hier heb je de datetime module geïmporteerd en een variabele genaamd utc_dt doorgegeven aan het index.html sjabloon met de waarde van datetime.datetime.utcnow(), wat de huidige UTC-datum en -tijd is.

Volgende, om de waarde van de variabele op de indexpagina weer te geven, open je het index.html bestand voor bewerken:

  1. nano templates/index.html

Bewerk het bestand zodat het er als volgt uitziet:

flask_app/templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>FlaskApp</title>
</head>
<body>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
    <h3>{{ utc_dt }}</h3>
</body>
</html>

Bewaar en sluit het bestand.

Je hebt een H3-kop toegevoegd met het speciale {{ ... }} scheidingsteken om de waarde van de utc_dt variabele af te drukken.

Open je browser en bezoek de indexpagina:

http://127.0.0.1:5000/

Je zult een pagina zien die lijkt op de volgende afbeelding:

Je hebt nu een indexpagina gemaakt met een HTML-sjabloon in je Flask-applicatie, een sjabloon weergegeven en een variabele waarde doorgegeven en weergegeven. Vervolgens vermijd je codeherhaling door gebruik te maken van sjabloonovererving.

Stap 2 — Sjabloonovererving gebruiken

In deze stap maak je een basisjabloon met inhoud die kan worden gedeeld met je andere sjablonen. Je bewerkt je indexsjabloon om over te erven van het basisjabloon. Vervolgens maak je een nieuwe pagina die dienst zal doen als de About-pagina van je applicatie, waar gebruikers meer informatie kunnen vinden over je applicatie.

Een basisjabloon bevat HTML-componenten die doorgaans worden gedeeld tussen alle andere sjablonen, zoals de titel van de applicatie, navigatiebalken en voetteksten.

Open eerst een nieuw bestand genaamd base.html voor bewerking in je sjablonenmap:

  1. nano templates/base.html

Schrijf de volgende code in je base.html bestand:

flask_app/templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="#">FlaskApp</a>
        <a href="#">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

Bewaar en sluit het bestand.

De meeste code in dit bestand is standaard HTML, een titel, wat styling voor de navigatielinks, een navigatiebalk met twee links, één voor de indexpagina en één voor de nog te maken About-pagina, en een <div> voor de inhoud van de pagina. (De links werken nog niet; de volgende stap zal tonen hoe je tussen pagina’s kunt navigeren).

De volgende gemarkeerde delen zijn echter specifiek voor de Jinja-sjabloonengine:

  • {% block title %} {% endblock %}: Een blok dat dient als een placeholder voor een titel. Je zult dit later gebruiken in andere templates om een aangepaste titel voor elke pagina in je applicatie te bieden zonder de hele <head> sectie elke keer opnieuw te schrijven.

  • {% block content %} {% endblock %}: Nog een blok dat vervangen zal worden door inhoud afhankelijk van het child template (een template dat overerft van base.html) dat het zal overschrijven.

Nu je een basis template hebt, kun je er gebruik van maken door middel van overerving. Open het index.html bestand:

  1. nano templates/index.html

Vervang dan de inhoud ervan met het volgende:

flask_app/templates/index.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Index {% endblock %}</h1>
    <h1>Hello World!</h1>
    <h2>Welcome to FlaskApp!</h2>
    <h3>{{ utc_dt }}</h3>
{% endblock %}

Hier gebruik je de `{% extends %}` tag om over te nemen van de `base.html` template. Vervolgens breid je deze uit door het `content` blok in de basis-template te vervangen door wat zich in het `content` blok in het vorige codeblok bevindt.

Dit contentblok bevat een `<h1>` tag met de tekst `Index` binnen een titelblok, dat op zijn beurt het oorspronkelijke `title` blok in de `base.html` template vervangt door de tekst `Index` zodat de volledige titel wordt `Index - FlaskApp`. Op deze manier kun je dezelfde tekst twee keer vermijden, aangezien het zowel als een titel voor de pagina als een kop fungeert die onder de navigatiebalk verschijnt, overgenomen van de basis-template.

Daarna heb je nog een paar koppen: één `<h1>` kop met de tekst `Hello World!`, een `<h2>` kop, en een `<h3>` kop met de waarde van de `utc_dt` variabele.

Template overerving geeft je de mogelijkheid om de HTML-code die je in andere templates hebt te hergebruiken (`base.html` in dit geval) zonder het elke keer dat het nodig is, te hoeven herhalen.

Bewaar en sluit het bestand en ververs de indexpagina in je browser. De pagina zal er als volgt uitzien:

Vervolgens zal je de About pagina aanmaken. Open het `app.py` bestand om een nieuwe route toe te voegen:

  1. nano app.py

Voeg de volgende route toe aan het einde van het bestand:

flask_app/app.py

# ...
@app.route('/about/')
def about():
    return render_template('about.html')

Hier gebruik je de app.route() decorator om een view functie te maken genaamd about(). Binnen deze functie retourneer je het resultaat van het aanroepen van de render_template() functie met de about.html template bestandsnaam als argument.

Bewaar en sluit het bestand.

Open een template bestand genaamd about.html om te bewerken:

  1. nano templates/about.html

Voeg de volgende code toe aan het bestand:

flask_app/templates/about.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} About {% endblock %}</h1>
    <h3>FlaskApp is a Flask web application written in Python.</h3>
{% endblock %}

Hier erf je van de basis template door gebruik te maken van de extends tag, vervang je het content blok van de basis template met een <h1> tag die ook dienst doet als de titel van de pagina, en voeg je een <h3> tag toe met wat informatie over de applicatie.

Bewaar en sluit het bestand.

Met de ontwikkelingsserver draaiend, bezoek de volgende URL met je browser:

http://127.0.0.1:5000/about

Je zult een pagina zien die er ongeveer zo uitziet:

Merk op hoe de navigatiebalk en een deel van de titel worden overgeërfd van de basis template.

Je hebt nu een basis template gemaakt en deze gebruikt in je index pagina en about pagina om code herhaling te voorkomen. De links in de navigatiebalk doen op dit moment nog niets. In de volgende stap leer je hoe je tussen routes in je templates kunt linken door de navigatiebalk links te repareren.

Stap 3 — Koppeling tussen Pagina’s

In deze stap leer je hoe je tussen pagina’s in je sjablonen kunt linken met behulp van de url_for() helperfunctie. Je zult twee links toevoegen aan de navigatiebalk in je basis-sjabloon, één voor de indexpagina en één voor de About-pagina.

Open eerst je basis-sjabloon voor bewerking:

  1. nano templates/base.html

Bewerk het bestand zodat het er als volgt uitziet:

flask_app/templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('hello') }}">FlaskApp</a>
        <a href="{{ url_for('about') }}">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

Hier gebruik je de speciale url_for() functie die de URL zal retourneren voor de view-functie die je eraan geeft. De eerste link verwijst naar de route van de hello() view-functie (die de indexpagina is). De tweede link verwijst naar de route van de about() view-functie. Merk op dat je de naam van de view-functie doorgeeft, niet de route (/ of /about).

Het gebruik van de url_for() functie om URL’s te bouwen helpt je om URL’s beter te beheren. Als je URL’s hard-codeert, zullen je links breken als je de routes bewerkt. Met url_for() kun je routes bewerken en garanderen dat de links nog steeds naar verwachting werken. De url_for() functie zorgt ook voor andere dingen, zoals het ontsnappen van speciale tekens.

Sla het bestand op en sluit het.

Ga nu naar de indexpagina en probeer de links in de navigatiebalk uit. Je zult zien dat ze naar verwachting werken.

Je hebt geleerd hoe je de functie url_for() kunt gebruiken om naar andere routes te linken in je sjablonen. Vervolgens voeg je enkele conditionele statements toe om te bepalen wat er in je sjablonen wordt weergegeven, afhankelijk van de voorwaarden die je instelt, en je gebruikt for-loops in je sjablonen om lijstitems weer te geven.

Stap 4 — Conditionele Statements en Loops Gebruiken

In deze stap gebruik je if-statements in je sjablonen om te bepalen wat er moet worden weergegeven afhankelijk van bepaalde voorwaarden. Je gebruikt ook for-loops om door Python-lijsten te gaan en elk item in de lijst weer te geven. Je voegt een nieuwe pagina toe die reacties in een lijst weergeeft. Reacties met een even indexnummer krijgen een blauwe achtergrond, en reacties met een oneven indexnummer worden weergegeven met een grijze achtergrond.

Eerst maak je een route aan voor de reactiepagina. Open je app.py bestand voor bewerking:

  1. nano app.py

Voeg de volgende route toe aan het einde van het bestand:

flask_app/app.py

# ...

@app.route('/comments/')
def comments():
    comments = ['This is the first comment.',
                'This is the second comment.',
                'This is the third comment.',
                'This is the fourth comment.'
                ]

    return render_template('comments.html', comments=comments)

In de bovenstaande route heb je een Python-lijst genaamd comments die vier items bevat. (Deze reacties zouden normaal gesproken uit een database komen in een echte situatie, in plaats van hardcoded zoals je hier hebt gedaan.) Je retourneert een sjabloonbestand genaamd comments.html in de laatste regel, waarbij je een variabele genaamd comments meegeeft die de lijst bevat naar het sjabloonbestand.

Sla het bestand op en sluit het.

Vervolgens opent u een nieuw bestand comments.html in de templates directory voor bewerking:

  1. nano templates/comments.html

Voeg de volgende code toe aan het bestand:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
        <div style="padding: 10px; background-color: #EEE; margin: 20px">
            <p style="font-size: 24px">{{ comment }}</p>
        </div>
        {% endfor %}
    </div>
{% endblock %}

Hier breidt u de base.html template uit en vervangt u de inhoud van het content blok. Eerst gebruikt u een <h1> kop die ook dient als de titel van de pagina.

U gebruikt een Jinja for loop in de regel {% for comment in comments %} om door elk commentaar in de comments lijst te gaan (die wordt opgeslagen in de comment variabele). U geeft het commentaar weer in de <p style="font-size: 24px">{{ comment }}</p> tag op dezelfde manier als u normaal gesproken een variabele in Jinja zou weergeven. U geeft het einde van de for loop aan met het {% endfor %} keyword. Dit is anders dan de manier waarop Python for loops worden opgebouwd omdat er geen speciale inspringing is in Jinja templates.

Sla het bestand op en sluit het.

Met de ontwikkelingsserver draaiend, opent u uw browser en bezoekt u de comments pagina:

http://127.0.0.1:5000/comments

U zult een pagina zien die er ongeveer als volgt uitziet:

Nu zult u de if conditionele statement in uw templates gebruiken door commentaren met een oneven indexnummer met een grijze achtergrond weer te geven, en commentaren met een even indexnummer met een blauwe achtergrond.

Open uw comments.html template bestand voor bewerking:

  1. nano templates/comments.html

Bewerk het om er als volgt uit te zien:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index % 2 == 0 %}
                {% set bg_color = '#e6f9ff' %}
            {% else %}
                {% set bg_color = '#eee' %}
            {% endif %}

            <div style="padding: 10px; background-color: {{ bg_color }}; margin: 20px">
                <p>#{{ loop.index }}</p>
                <p style="font-size: 24px">{{ comment }}</p>
            </div>
        {% endfor %}
    </div>
{% endblock %}

Met deze nieuwe bewerking heb je een if statement toegevoegd in de regel {% if loop.index % 2 == 0 %}. De loop variabele is een speciale Jinja-variabele die je toegang geeft tot informatie over de huidige loop. Hier gebruik je loop.index om de index van het huidige item te krijgen, die begint vanaf 1, niet 0 zoals in Python-lijsten.

Het if statement controleert hier of de index even is met behulp van de % operator. Het controleert de rest bij deling van het indexnummer door 2; als de rest 0 is, betekent dit dat het indexnummer even is, anders is het indexnummer oneven. Je gebruikt de {% set %} tag om een variabele genaamd bg_color te declareren. Als het indexnummer even is, stel je deze in op een blauwachtige kleur, anders, als het indexnummer oneven is, stel je de bg_color variabele in op grijs. Vervolgens gebruik je de bg_color variabele om een achtergrondkleur in te stellen voor de <div> tag die de commentaar bevat. Boven de tekst van het commentaar gebruik je loop.index om het huidige indexnummer weer te geven in een <p> tag.

Bewaar en sluit het bestand.

Open je browser en bezoek de comments pagina:

http://127.0.0.1:5000/comments

Je zult je nieuwe Comments pagina zien:

Dit was een demonstratie van hoe je het if statement kunt gebruiken. Maar je kunt hetzelfde effect ook bereiken door de speciale loop.cycle() Jinja helper te gebruiken. Om dit te demonstreren, open het comments.html bestand:

  1. nano templates/comments.html
flask_app/templates/comments.html

{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            <div style="padding: 10px;
                        background-color: {{ loop.cycle('#EEE', '#e6f9ff') }};
                        margin: 20px">
                <p>#{{ loop.index }}</p>
                <p style="font-size: 24px">{{ comment }}</p>
            </div>
        {% endfor %}
    </div>
{% endblock %}

Hier heb je de if/else statement verwijderd en de loop.cycle('#EEE', '#e6f9ff') helper gebruikt om tussen de twee kleuren te wisselen. De waarde van background-color zal één keer #EEE zijn en een andere keer #e6f9ff.

Bewaar en sluit het bestand.

Open de comments pagina in je browser, ververs deze en je zult zien dat dit hetzelfde effect heeft als de if statement.

Je kunt if statements gebruiken voor meerdere doeleinden, waaronder het bepalen wat er op de pagina wordt weergegeven. Bijvoorbeeld, om alle comments behalve de tweede weer te geven, kun je een if statement gebruiken met de conditie loop.index != 2 om de tweede comment uit te filteren.

Open de comments template:

  1. nano templates/comments.html

En bewerk het als volgt:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment }}</p>
                </div>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

Hier gebruik je {% if loop.index != 2 %} om alleen de comments te tonen die niet de index 2 hebben, wat betekent alle comments behalve de tweede. Je gebruikt ook een hard-gecodeerde waarde voor de achtergrondkleur in plaats van de loop.cycle() helper om het eenvoudiger te maken, en de rest blijft ongewijzigd. Je beëindigt de if statement met {% endif %}.

Bewaar en sluit het bestand.

Ververs de comments pagina en je zult zien dat de tweede comment niet wordt weergegeven.

Je moet nu een link toevoegen die gebruikers naar de Comments pagina brengt in de navigatiebalk. Open de basis template voor bewerking:

  1. nano templates/base.html

Bewerk de inhoud van de <nav> tag door een nieuwe <a> link toe te voegen:

flask_app/templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %} {% endblock %} - FlaskApp</title>
    <style>
        nav a {
            color: #d64161;
            font-size: 3em;
            margin-left: 50px;
            text-decoration: none;
        }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('hello') }}">FlaskApp</a>
        <a href="{{ url_for('comments') }}">Comments</a>
        <a href="{{ url_for('about') }}">About</a>
    </nav>
    <hr>
    <div class="content">
        {% block content %} {% endblock %}
    </div>
</body>
</html>

Hier gebruik je de url_for() helper om te linken naar de comments() view functie.

Sla het bestand op en sluit het.

De navigatiebalk heeft nu een nieuwe link die naar de comments pagina linkt.

Je hebt if statements gebruikt in je templates om te bepalen wat er moet worden weergegeven afhankelijk van bepaalde voorwaarden. Je hebt for loops gebruikt om door Python lijsten te gaan en elk item in de lijst weer te geven, en je hebt geleerd over de speciale loop variabele in Jinja. Vervolgens gebruik je Jinja filters om te bepalen hoe variabele data wordt weergegeven.

Stap 5 — Filters gebruiken

In deze stap leer je hoe je Jinja filters kunt gebruiken in je templates. Je gebruikt de upper filter om de comments die je in de vorige stap hebt toegevoegd naar hoofdletters te converteren, je gebruikt de join filter om een reeks strings samen te voegen tot één string, en je leert hoe je vertrouwde HTML-code kunt weergeven zonder het te escapen met de safe filter.

Eerst zul je de comments op de comments pagina naar hoofdletters converteren. Open de comments.html template voor bewerking:

  1. nano templates/comments.html

Bewerk het zodat het er als volgt uitziet:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
    </div>
{% endblock %}

Hier heb je de upper filter toegevoegd met het pijp-symbool (|). Dit zal de waarde van de comment variabele wijzigen om hoofdletters te zijn.

Bewaar en sluit het bestand.

Met de ontwikkelingsserver actief, open de comments pagina met je browser:

http://127.0.0.1:5000/comments

Je kunt zien dat de comments allemaal in hoofdletters zijn na het toepassen van de filter.

Filters kunnen ook argumenten aannemen tussen haakjes. Om dit te demonstreren, zul je de join filter gebruiken om alle comments in de comments lijst samen te voegen.

Open de comments template:

  1. nano templates/comments.html

Bewerk het om er als volgt uit te zien:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            <p>{{ comments | join(" | ") }}</p>
        </div>
    </div>
{% endblock %}

Hier heb je een <hr> tag en een <div> tag toegevoegd waar je alle comments in de comments lijst samenvoegt met de join() filter.

Bewaar en sluit het bestand.

Ververs de comments pagina en je zult een pagina zien die er ongeveer als volgt uitziet:

Zoals je kunt zien, wordt de comments lijst weergegeven met de comments gescheiden door een pijp-symbool, wat je hebt doorgegeven aan de join() filter.

Een andere belangrijke filter is de safe filter, waarmee je vertrouwde HTML op de browser kunt weergeven. Om dit te illustreren, voeg je wat tekst met een HTML-tag toe aan je commentaartemplate met behulp van het {{ }} Jinja-scheidingsteken. In een echte situatie zou dit als een variabele van de server komen. Vervolgens wijzig je het join() argument om het <hr> tag te zijn in plaats van het pijp-symbool.

Open het commentaartemplate:

  1. nano templates/comments.html

Wijzig het om er als volgt uit te zien:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            {{ "<h1>COMMENTS</h1>" }}
            <p>{{ comments | join(" <hr> ") }}</p>
        </div>
    </div>
{% endblock %}

Hier heb je de waarde "<h1>COMMENTS</h1>" toegevoegd en het join-argument gewijzigd naar de <hr> tag.

Bewaar en sluit het bestand.

Vernieuw de commentaarpagina en je zult een pagina zien die er ongeveer als volgt uitziet:

Zoals je kunt zien, werden de HTML-tags niet weergegeven. Dit is een veiligheidsfunctie in Jinja, omdat sommige HTML-tags schadelijk kunnen zijn en tot een Cross Site Scripting (XSS) aanval kunnen leiden. Je zou alleen vertrouwde HTML in de browser moeten weergeven.

Om de HTML-tags hierboven weer te geven, open je het commentaartemplatebestand:

  1. nano templates/comments.html

Wijzig het door de safe filter toe te voegen:

flask_app/templates/comments.html
{% extends 'base.html' %}

{% block content %}
    <h1>{% block title %} Comments {% endblock %}</h1>
    <div style="width: 50%; margin: auto">
        {% for comment in comments %}
            {% if loop.index != 2 %}
                <div style="padding: 10px;
                            background-color: #EEE;
                            margin: 20px">
                    <p>#{{ loop.index }}</p>
                    <p style="font-size: 24px">{{ comment | upper }}</p>
                </div>
            {% endif %}
        {% endfor %}
        <hr>
        <div>
            {{ "<h1>COMMENTS</h1>" | safe }}
            <p>{{ comments | join(" <hr> ") | safe }}</p>
        </div>
    </div>
{% endblock %}

Je kunt zien dat je ook filters kunt ketenen, zoals in de regel <p>{{ comments | join(" <hr> ") | safe }}</p>. Elk filter wordt toegepast op het resultaat van de vorige filtering.

Bewaar en sluit het bestand.

Vernieuw de commentaarpagina en je zult zien dat de HTML-tags nu zoals verwacht worden weergegeven:

Waarschuwing: Het gebruik van het safe filter op HTML van onbekende bronnen kan uw applicatie blootstellen aan XSS-aanvallen. Gebruik het niet tenzij de HTML die u rendert afkomstig is van een vertrouwde bron.

Voor meer informatie, bekijk de lijst met ingebouwde Jinja filters.

Je hebt nu geleerd hoe je filters in je Jinja-sjablonen kunt gebruiken om variabele waarden aan te passen. Vervolgens integreer je het Bootstrap toolkit om je applicatie te stylen.

Stap 6 — Bootstrap integreren

In deze stap leer je hoe je het Bootstrap toolkit kunt gebruiken om je applicatie te stylen. Je voegt een Bootstrap navigatiebalk toe in het basis-sjabloon die zal verschijnen op alle pagina’s die van het basis-sjabloon erven.

Het Bootstrap toolkit helpt je je applicatie er visueel aantrekkelijker uit te laten zien. Het helpt je ook om responsive webpagina’s in je webapplicatie te implementeren, zodat het goed werkt op mobiele browsers zonder zelf HTML, CSS en JavaScript code te hoeven schrijven om deze doelen te bereiken.

Om Bootstrap te gebruiken, moet je het toevoegen aan het basis-sjabloon zodat je het in alle andere sjablonen kunt gebruiken.

Open je base.html template voor bewerking:

  1. nano templates/base.html

Bewerk het zodat het er als volgt uitziet:

flask_app/templates/base.html
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">

    <title>{% block title %} {% endblock %} - FlaskApp</title>
  </head>
  <body>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
    <div class="container-fluid">
        <a class="navbar-brand" href="{{ url_for('hello') }}">FlaskApp</a>
        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
        </button>
        <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
            <li class="nav-item">
              <a class="nav-link" href="{{ url_for('comments') }}">Comments</a>
            </li>
            <li class="nav-item">
              <a class="nav-link" href="{{ url_for('about') }}">About</a>
            </li>
        </ul>
        </div>
    </div>
    </nav>
    <div class="container">
        {% block content %} {% endblock %}
    </div>

    <!-- Optional JavaScript -->

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-U1DAWAznBHeqEIlVSCgzq+c9gqGAJn5c/t99JyeKa9xxaYpSvHU5awsuZVVFIhvj" crossorigin="anonymous"></script>

  </body>
</html>

Het grootste deel van de bovenstaande code is Bootstrap boilerplate dat nodig is om het te gebruiken. Je hebt enkele meta tags, een link naar het Bootstrap CSS-bestand in de <head> sectie, en onderaan heb je een link naar optionele JavaScript. De gemarkeerde delen van de code bevatten Jinja code die in de vorige stappen is uitgelegd. Let op hoe je specifieke tags en CSS-klassen gebruikt om Bootstrap te vertellen hoe elk element weergegeven moet worden.

In de <nav> tag hierboven heb je een <a> tag met de klasse navbar-brand, die de merklink in de navigatiebalk bepaalt. Binnen de <ul class="navbar-nav"> tag heb je reguliere navigatiebalkitems binnen een <a> tag in een <li> tag.

Voor meer informatie over deze tags en CSS-klassen, zie de Bootstrap componenten.

Bewaar en sluit het bestand.

Met de ontwikkelingsserver actief, open de indexpagina met je browser:

http://127.0.0.1:5000/

Je ziet een pagina die er ongeveer als volgt uitziet:

Je kunt nu Bootstrap componenten gebruiken om items in je Flask applicatie te stylen in al je templates.

Conclusie

Je weet nu hoe je HTML-sjablonen kunt gebruiken in je Flask webapplicatie. Je hebt variabelen gebruikt om gegevens van de server naar sjablonen door te geven, sjabloonovererving toegepast om herhaling te voorkomen, elementen zoals if-voorwaarden en for-lussen ingebouwd, en tussen verschillende pagina’s gelinkt. Je hebt geleerd over filters om tekst te wijzigen en vertrouwde HTML weer te geven, en je hebt Bootstrap in je applicatie geïntegreerd.

Als je meer wilt lezen over Flask, bekijk dan de Flask onderwerppagina.

Source:
https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-a-flask-application