cs253 »

CS253 Appendix B

Naturally, you want to take the HTML that you use to generate your web page out of your Python code and into a template document, right? Well, AppEngine comes with a templating engine that can help you do just that!


Jinja2 is a powerful templating engine modeled after Django's templating system. The idea is to separate your logic from your presentation, and make your code clean and well-defined in the process.

Here's the basic process to get it working in AppEngine.

Step 1: Modify 'app.yaml'

Open app.yaml from your AppEngine project directory in the editor of your choice. You need to do a few things here: 1) change the runtime attribute to python27, 2) add threadsafe: true, and 3) add the Jinja2 library in the configuration. Here's what your app.yaml might look like after you're done:

application: foobar
version: 1
runtime: python27
api_version: 1
threadsafe: true

- name: jinja2
  version: latest

- url: /.*
  script: main.app

The important bit is the libraries section - that's where you grant access to Jinja2.

Step 2: Move your HTML to a separate file

For the sake of this example, let's create a directory in your project folder called templates. Place your HTML code into a file called, let's say, index.html, underneath your templates folder.

Note: do not add a static_dir URL handler in your app.yaml file. A 'static_dir' handler is used to expose a directory of files to the client - things like images, static JavaScript files, stylesheets, etc. It turns out that AppEngine stores these files in a separate location than your app files, for efficiency reasons. This means that if you unintentionally set, say, your templates directory as a static_dir, then your app will throw an error every time you try to use a template, because the files won't be accessible!

Now, you have to add template placeholders to your HTML. Jinja2 has a default (and quite rich) syntax that it uses to generate filled-in HTML from your templates. Here's a simple example:

<!DOCTYPE html>
        <title>Look Ma, I'm using Jinja!</title>
        Hi there - I'm {{ name }}, and I {{ verb }} programming!

The placeholders and are what Jinja2 replaces with the data that your app provides. Remember these names - you'll have to use them when you send data to the templating engine. Almost done!

Step 3: Modify your main Python script to use Jinja2

Obviously, if you haven't already, remove the form = """<html... stuff from your Python file - that's what the template is for.

Now we must import the jinja2 module, and create an "environment" using which we can access the templating functions. Here's what the top section of your script might look like:

import os
import webapp2

import jinja2

jinja_environment = jinja2.Environment(autoescape=True,
    loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))

A few things to note here: the jinja2.Environment object that we're instantiating takes a loader argument, which takes a directory from which it can load templates; we've imported the os module just so that we can use its path manipulation functions to get the path to our templates directory. Notice also that we've used the autoescape=True argument - this makes Jinja2 escape all dangerous strings for us, so we don't have to!

Finally, to use the template in one of our request handlers, use something like this:

class MainPage(webapp2.RequestHandler):
    def get(self):
        template_values = {
            'name': 'SomeGuy',
            'verb': 'extremely enjoy'

        template = jinja_environment.get_template('index.html')

First we create a dictionary with the name/value pairs for the template - notice that the keys are the same as those included in the template. Then we retrieve a template object using jinja_environment.get_template, and finally we render and write out the resulting HTML using template.render(template_values).

And that's it! Try it out!