Documentation in progress Edit me on GitHub

12: Templating With jinja2

We just said Pyramid doesn't prefer one templating language over another. Time to prove it. Jinja2 is a popular templating system, used in Flask and modelled after Django's templates. Let's add pyramid_jinja2, a Pyramid add-on which enables Jinja2 as a renderer in our Pyramid applications.

Objectives

  • Show Pyramid's support for different templating systems
  • Learn about installing Pyramid add-ons

Steps

  1. In this step let's start by installing the pyramid_jinja2 add-on, the copying the view_class step's directory:

    $ cd ..; cp -r view_classes jinja2; cd jinja2
    $ $VENV/bin/python setup.py develop
    $ $VENV/bin/easy_install pyramid_jinja2
    
  2. We need to include pyramid_jinja2 in jinja2/tutorial/__init__.py:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    from pyramid.config import Configurator
    
    
    def main(global_config, **settings):
        config = Configurator(settings=settings)
        config.include('pyramid_jinja2')
        config.add_route('home', '/')
        config.add_route('hello', '/howdy')
        config.scan('.views')
        return config.make_wsgi_app()
    
  3. Our jinja2/tutorial/views.py simply changes its renderer:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    from pyramid.view import (
        view_config,
        view_defaults
        )
    
    
    @view_defaults(renderer='home.jinja2')
    class TutorialViews:
        def __init__(self, request):
            self.request = request
    
        @view_config(route_name='home')
        def home(self):
            return {'name': 'Home View'}
    
        @view_config(route_name='hello')
        def hello(self):
            return {'name': 'Hello View'}
    
  4. Add jinja2/tutorial/home.jinja2 as a template:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>Quick Tour: {{ name }}</title>
    </head>
    <body>
    <h1>Hi {{ name }}</h1>
    </body>
    </html>
    
  5. Get the pyramid.includes into the functional test setup in jinja2/tutorial/tests.py:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    import unittest
    
    from pyramid import testing
    
    
    class TutorialViewTests(unittest.TestCase):
        def setUp(self):
            self.config = testing.setUp()
    
        def tearDown(self):
            testing.tearDown()
    
        def test_home(self):
            from .views import TutorialViews
    
            request = testing.DummyRequest()
            inst = TutorialViews(request)
            response = inst.home()
            self.assertEqual('Home View', response['name'])
    
        def test_hello(self):
            from .views import TutorialViews
    
            request = testing.DummyRequest()
            inst = TutorialViews(request)
            response = inst.hello()
            self.assertEqual('Hello View', response['name'])
    
    
    class TutorialFunctionalTests(unittest.TestCase):
        def setUp(self):
            from tutorial import main
    
            settings = {
                'pyramid.includes': [
                    'pyramid_jinja2'
                ]
            }
            app = main({}, **settings)
            from webtest import TestApp
    
            self.testapp = TestApp(app)
    
        def test_home(self):
            res = self.testapp.get('/', status=200)
            self.assertIn(b'<h1>Hi Home View', res.body)
    
        def test_hello(self):
            res = self.testapp.get('/howdy', status=200)
            self.assertIn(b'<h1>Hi Hello View', res.body)
    
  6. Now run the tests:

    $ $VENV/bin/nosetests tutorial
    
  7. Run your Pyramid application with:

    $ $VENV/bin/pserve development.ini --reload
    
  8. Open http://localhost:6543/ in your browser.

Analysis

Getting a Pyramid add-on into Pyramid is simple. First you use normal Python package installation tools to install the add-on package into your Python. You then tell Pyramid's configurator to run the setup code in the add-on. In this case the setup code told Pyramid to make a new "renderer" available that looked for .jinja2 file extensions.

Our view code stayed largely the same. We simply changed the file extension on the renderer. For the template, the syntax for Chameleon and Jinja2's basic variable insertion is very similar.

Our functional tests don't have development.ini so they needed the pyramid.includes to be setup in the test setup.

Extra Credit

  1. Our project now depends on pyramid_jinja2. We installed that dependency manually. What is another way we could have made the association?
  2. We used development.ini to get the configurator to load pyramid_jinja2's configuration. What is another way could include it into the config?

Table Of Contents

Previous topic

11: Dispatching URLs To Views With Routing

Next topic

13: CSS/JS/Images Files With Static Assets