Web development usually involves HTML, and web frameworks generally provide support for HTML generation using templating languages.
Pyramid provides bundled support for the Chameleon and Mako templating engines, with active community support for bindings such as Jinja2.
Again, let’s use the previous package as a starting point for a new distribution. Also, make a directory for the templates:
(env33)$ cd ../..; cp -r step05 step06; cd step06
(env33)$ python3.3 setup.py develop
(env33)$ mkdir tutorial/templates
Our tutorial/views.py is now data-centric:
1 2 3 4 5 | from pyramid.view import view_config
@view_config(route_name='hello', renderer='templates/wiki_view.pt')
def hello_world(request):
return dict(title='Hello World')
|
Create a Chameleon template in tutorial/templates/wiki_view.pt:
1 2 3 4 5 6 7 8 9 10 <html> <head> <title>${title}</title> </head> <body> <div> <h1>${title}</h1> </div> </body> </html>
Our tutorial/tests.py has a unit test which is also now data-centric:
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 import unittest from pyramid import testing class ViewTests(unittest.TestCase): def setUp(self): self.config = testing.setUp() def tearDown(self): testing.tearDown() def test_my_view(self): from tutorial.views import hello_world request = testing.DummyRequest() response = hello_world(request) self.assertEqual(response['title'], 'Hello World') class FunctionalTests(unittest.TestCase): def setUp(self): from tutorial import main settings = {} app = main(settings) from webtest import TestApp self.testapp = TestApp(app) def test_it(self): res = self.testapp.get('/', status=200) self.assertIn(b'Hello', res.body)
Run the tests in your package using nose:
(env33)$ nosetests .
..
-----------------------------------------------------------------
Ran 2 tests in 1.971s
OK
Run the WSGI application. Note the --reload:
(env33)$ pserve development.ini --reload
Open http://127.0.0.1:6547/ in your browser.
Edit the template and reload your browser to see the changes. Do the same on the title returned in views.py.
Our view function changed significantly. It is now a callable that returns data, which makes test-writing much more meaningful. Our @view_config wraps the view with a renderer that is pointed at a Chameleon template. Pyramid knows from the file suffix .pt that this should use the Chameleon engine for rendering the response.
The use of a templates directory is purely a matter of taste. You don’t have to have a magically-named directory, or any subdirectory at all.
Each kind of renderer (Chameleon, Mako, JSON, add-on renderers such as Jinja) manage what goes into the namespace of the template. Chameleon provides request automatically, for example, as well as the data returned from the view.
The --reload argument to pserve makes it watch for changes to certain kinds of files. For example, if you change a .py file, the application will restart automatically.