Générer du contenu dynamique à partir de modèles


Cette partie du tutoriel consacré au code de l'application Guestbook pour Python explique comment utiliser les modèles Jinja pour générer du contenu Web dynamique.

Ce tutoriel comporte plusieurs pages. Pour le suivre depuis le début et consulter les instructions relatives à la configuration, consultez la page Créer un livre d'or.

Il est conseillé d'éviter les imbrications de code HTML, car cela génère un code brouillon et difficile à gérer. Utilisez de préférence un système de création de modèles permettant d'isoler le code HTML dans un fichier distinct avec une syntaxe spéciale, afin d'indiquer l'emplacement des données issues de l'application. Il existe de nombreux systèmes de création de modèles pour Python, dont EZT, Cheetah, ClearSilver, Quixote, Django et Jinja2. Vous pouvez utiliser le moteur de création de modèles de votre choix en l'incorporant au code de votre application.

Pour plus de commodité, App Engine inclut les moteurs de création de modèles Django et Jinja2.

Utilisation de modèles jinja2

Le fichier app.yaml répertorie la dernière version de jinja2 en tant que bibliothèque requise. Les applications de production doivent utiliser un numéro de version réel plutôt que version: latest.

libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest

L'application importe jinja2 et crée un objet jinja2.Environment.

import os
import urllib

from google.appengine.api import users
from google.appengine.ext import ndb

import jinja2
import webapp2

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)

La méthode get du gestionnaire de requêtes MainPage forme un dictionnaire de paires clé/valeur qu'elle transmet à template.render.

class MainPage(webapp2.RequestHandler):

    def get(self):
        guestbook_name = self.request.get('guestbook_name',
                                          DEFAULT_GUESTBOOK_NAME)
        greetings_query = Greeting.query(
            ancestor=guestbook_key(guestbook_name)).order(-Greeting.date)
        greetings = greetings_query.fetch(10)

        user = users.get_current_user()
        if user:
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'

        template_values = {
            'user': user,
            'greetings': greetings,
            'guestbook_name': urllib.quote_plus(guestbook_name),
            'url': url,
            'url_linktext': url_linktext,
        }

        template = JINJA_ENVIRONMENT.get_template('index.html')
        self.response.write(template.render(template_values))

La page est affichée conformément au modèle index.html, qui reçoit le dictionnaire en tant qu'entrée.

{% for greeting in greetings %}
<div class="row">
  {% if greeting.author %}
    <b>{{ greeting.author.email }}
      {% if user and user.user_id() == greeting.author.identity %}
        (You)
      {% endif %}
    </b> wrote:
  {% else %}
    An anonymous person wrote:
  {% endif %}
  <blockquote>{{ greeting.content }}</blockquote>
</div>
{% endfor %}

La méthode JINJA_ENVIRONMENT.get_template(name) prend le nom d'un fichier modèle et renvoie un objet modèle. L'appel template.render(template_values) utilise un dictionnaire de valeurs et renvoie le texte mis en forme. Le modèle utilise la syntaxe de création de modèles Jinja2 pour accéder aux valeurs et les parcourir. Il peut, en outre, faire référence aux propriétés de ces valeurs.