Como gerar conteúdo dinâmico usando modelos

Nesta parte da explicação sobre o código do Python Guestbook, você aprende a usar os modelos Jinja para gerar conteúdo dinâmico da Web.

Esta página é parte de um tutorial com várias páginas. Para começar e ver as instruções de configuração, acesse Como criar um aplicativo de livro de visitas.

HTML incorporado ao código é complicado e difícil de manter. É melhor usar um sistema de modelos em que o HTML seja mantido em um arquivo separado, com uma sintaxe especial, para indicar a localização dos dados do aplicativo. EZT, Cheetah, ClearSilver, Quixote, Django, e Jinja2 são apenas alguns dos muitos sistemas de modelos para Python. Use o mecanismo de modelos que preferir e o agrupe com o código do aplicativo.

Para sua conveniência, o App Engine inclui os mecanismos de modelos Django e Jinja2.

Como usar modelos Jinja2

O arquivo app.yaml lista a versão mais recente do jinja2 como uma biblioteca obrigatória. Os aplicativos de produção precisam usar um número da versão real em vez de version: latest.

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

O app importa jinja2 e cria um objeto 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)

O método get para o gerenciador de solicitações MainPage forma um dicionário de pares de chave-valor e o transmite para 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))

A página é renderizada de acordo com o modelo index.html, que recebe o dicionário como entrada.

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

O método JINJA_ENVIRONMENT.get_template(name) usa o nome de um arquivo de modelo e retorna um objeto de modelo. A chamada template.render(template_values) usa um dicionário de valores e retorna o texto renderizado. O modelo usa a sintaxe de modelos Jinja2 para acessar e iterar os valores, além de se referir a propriedades desses valores.