使用模板生成动态内容


Python 留言板代码演示的这一部分介绍了如何使用 Jinja 模板生成动态网页内容。

本页面是多页教程中的一页。如需从头开始并查看设置说明,请转到创建留言板

嵌入代码中的 HTML 杂乱且难以维护。最好使用模板系统,在模板系统中,HTML 会保存在使用特殊语法的单独文件中,以指示应用中的数据所显示的位置。Python 提供多种模板系统:EZTCheetahClearSilverQuixoteDjangoJinja2 等(这些只是其中一小部分)。您可以通过将选择的模板引擎与您的应用代码相互绑定来使用该模板引擎。

App Engine 包含 Django 和 Jinja2 模板引擎,以便于您使用。

使用 Jinja2 模板

app.yaml 文件将最新版本的 jinja2 列为必需的库。 正式应用应当使用实际版本号,而非 version: latest

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

应用会导入 jinja2 并创建一个 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)

MainPage 请求处理程序的 get 方法会生成一个键/值对字典,并将其传递给 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))

该页面根据 index.html 模板呈现,该模板会接收字典作为输入。

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

JINJA_ENVIRONMENT.get_template(name) 方法采用模板文件的名称并返回一个模板对象。template.render(template_values) 调用会接受值字典,并返回呈现的文本。该模板使用 Jinja2 模板语法来访问值并遍历这些值,而且可以引用这些值的属性。