Generazione di contenuti dinamici da modelli


Questa parte della procedura dettagliata del codice del guestbook Python mostra come utilizzare i modelli Jinja per generare contenuti web dinamici.

Questa pagina fa parte di un tutorial multi pagina. Per partire dall'inizio e vedere le istruzioni per la configurazione, vai a Creare un guestbook.

L'HTML incorporato nel codice è disordinato e difficile da gestire. È preferibile utilizzare un sistema di modelli, in cui l'HTML viene conservato in un file separato con sintassi speciale per indicare dove vengono visualizzati i dati dell'applicazione. Esistono molti sistemi di modelli per Python: EZT, Cheetah, ClearSilver, Quixote, Django e Jinja2 sono solo alcuni. Puoi utilizzare il motore che preferisci raggruppandolo con il codice dell'applicazione.

Per praticità, App Engine include i motori dei modelli Django e Jinja2.

Utilizzo dei modelli Jinja2

Il file app.yaml elenca la versione più recente di jinja2 come libreria obbligatoria. Le applicazioni di produzione dovrebbero utilizzare un numero di versione effettivo anziché version: latest.

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

L'app importa jinja2 e crea un oggetto 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)

Il metodo get per il gestore delle richieste MainPage forma un dizionario di coppie chiave/valore e lo passa a 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 pagina viene visualizzata in base al modello index.html, che riceve il dizionario come input.

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

Il metodo JINJA_ENVIRONMENT.get_template(name) prende il nome di un file modello e restituisce un oggetto modello. La chiamata template.render(template_values) prende un dizionario di valori e restituisce il testo visualizzato. Il modello utilizza la sintassi del modello Jinja2 per accedere ai valori ed eseguire l'iterazione, e può fare riferimento alle proprietà di questi valori.