Templates¶
A template is a file on disk which can be used to render dynamic data provided by a view. Pyramid offers a number of ways to perform templating tasks out of the box, and provides add-on templating support through a set of bindings packages.
Before discussing how built-in templates are used in detail, we'll discuss two ways to render templates within Pyramid in general: directly, and via renderer configuration.
Using Templates Directly¶
The most straightforward way to use a template within Pyramid is to cause it to be rendered directly within a view callable. You may use whatever API is supplied by a given templating engine to do so.
Pyramid provides various APIs that allow you to render templates
directly from within a view callable. For example, if there is a
Chameleon ZPT template named foo.pt
in a directory named
templates
in your application, you can render the template from
within the body of a view callable like so:
1 2 3 4 5 6 | from pyramid.renderers import render_to_response
def sample_view(request):
return render_to_response('templates/foo.pt',
{'foo':1, 'bar':2},
request=request)
|
The sample_view
view callable function above returns a
response object which contains the body of the
templates/foo.pt
template. In this case, the templates
directory should live in the same directory as the module containing
the sample_view
function. The template author will have the names
foo
and bar
available as top-level names for replacement or
comparison purposes.
In the example above, the path templates/foo.pt
is relative to the
directory containing the file which defines the view configuration.
In this case, this is the directory containing the file that
defines the sample_view
function. Although a renderer path is
usually just a simple relative pathname, a path named as a renderer
can be absolute, starting with a slash on UNIX or a drive letter
prefix on Windows. The path can alternately be an
asset specification in the form
some.dotted.package_name:relative/path
. This makes it possible to
address template assets which live in another package. For example:
1 2 3 4 5 6 | from pyramid.renderers import render_to_response
def sample_view(request):
return render_to_response('mypackage:templates/foo.pt',
{'foo':1, 'bar':2},
request=request)
|
An asset specification points at a file within a Python package.
In this case, it points at a file named foo.pt
within the
templates
directory of the mypackage
package. Using an
asset specification instead of a relative template name is usually
a good idea, because calls to render_to_response()
using asset specifications will continue to work properly if you move the
code containing them to another location.
In the examples above we pass in a keyword argument named request
representing the current Pyramid request. Passing a request
keyword argument will cause the render_to_response
function to
supply the renderer with more correct system values (see
System Values Used During Rendering), because most of the information required
to compose proper system values is present in the request. If your
template relies on the name request
or context
, or if you've
configured special renderer globals, make sure to pass
request
as a keyword argument in every call to a
pyramid.renderers.render_*
function.
Every view must return a response object, except for views
which use a renderer named via view configuration (which we'll
see shortly). The pyramid.renderers.render_to_response()
function is a shortcut function that actually returns a response
object. This allows the example view above to simply return the result
of its call to render_to_response()
directly.
Obviously not all APIs you might call to get response data will return a
response object. For example, you might render one or more templates to
a string that you want to use as response data. The
pyramid.renderers.render()
API renders a template to a string. We
can manufacture a response object directly, and use that string
as the body of the response:
1 2 3 4 5 6 7 8 9 | from pyramid.renderers import render
from pyramid.response import Response
def sample_view(request):
result = render('mypackage:templates/foo.pt',
{'foo':1, 'bar':2},
request=request)
response = Response(result)
return response
|
Because view callable functions are typically the only code in Pyramid that need to know anything about templates, and because view functions are very simple Python, you can use whatever templating system you're most comfortable with within Pyramid. Install the templating system, import its API functions into your views module, use those APIs to generate a string, then return that string as the body of a Pyramid Response object.
For example, here's an example of using "raw" Mako from within a Pyramid view:
1 2 3 4 5 6 7 8 | from mako.template import Template
from pyramid.response import Response
def make_view(request):
template = Template(filename='/templates/template.mak')
result = template.render(name=request.params['name'])
response = Response(result)
return response
|
You probably wouldn't use this particular snippet in a project, because it's easier to use the supported Mako bindings. But if your favorite templating system is not supported as a renderer extension for Pyramid, you can create your own simple combination as shown above.
Note
If you use third-party templating languages without cooperating Pyramid bindings directly within view callables, the auto-template-reload strategy explained in Automatically Reloading Templates will not be available, nor will the template asset overriding capability explained in Overriding Assets be available, nor will it be possible to use any template using that language as a renderer. However, it's reasonably easy to write custom templating system binding packages for use under Pyramid so that templates written in the language can be used as renderers. See Adding and Changing Renderers for instructions on how to create your own template renderer and Available Add-On Template System Bindings for example packages.
If you need more control over the status code and content-type, or other response attributes from views that use direct templating, you may set attributes on the response that influence these values.
Here's an example of changing the content-type and status of the
response object returned by
render_to_response()
:
1 2 3 4 5 6 7 8 9 | from pyramid.renderers import render_to_response
def sample_view(request):
response = render_to_response('templates/foo.pt',
{'foo':1, 'bar':2},
request=request)
response.content_type = 'text/plain'
response.status_int = 204
return response
|
Here's an example of manufacturing a response object using the result
of render()
(a string):
1 2 3 4 5 6 7 8 9 10 | from pyramid.renderers import render
from pyramid.response import Response
def sample_view(request):
result = render('mypackage:templates/foo.pt',
{'foo':1, 'bar':2},
request=request)
response = Response(result)
response.content_type = 'text/plain'
return response
|
System Values Used During Rendering¶
When a template is rendered using
render_to_response()
or
render()
, or a renderer=
argument to view
configuration (see Templates Used as Renderers via Configuration), the renderer
representing the template will be provided with a number of system values.
These values are provided to the template:
request
- The value provided as the
request
keyword argument torender_to_response
orrender
or the request object passed to the view when therenderer=
argument to view configuration is being used to render the template. req
- An alias for
request
. context
- The current Pyramid context if
request
was provided as a keyword argument torender_to_response
orrender
, orNone
if therequest
keyword argument was not provided. This value will always be provided if the template is rendered as the result of arenderer=
argument to view configuration being used. renderer_name
- The renderer name used to perform the rendering,
e.g.
mypackage:templates/foo.pt
. renderer_info
- An object implementing the
pyramid.interfaces.IRendererInfo
interface. Basically, an object with the following attributes:name
,package
andtype
. view
- The view callable object that was used to render this template. If the
view callable is a method of a class-based view, this will be an instance
of the class that the method was defined on. If the view callable is a
function or instance, it will be that function or instance. Note that this
value will only be automatically present when a template is rendered as a
result of a
renderer=
argument; it will beNone
when therender_to_response
orrender
APIs are used.
You can define more values which will be passed to every template executed as a result of rendering by defining renderer globals.
What any particular renderer does with these system values is up to the renderer itself, but most template renderers make these names available as top-level template variables.
Templates Used as Renderers via Configuration¶
An alternative to using render_to_response()
to render templates manually in your view callable code, is
to specify the template as a renderer in your
view configuration. This can be done with any of the
templating languages supported by Pyramid.
To use a renderer via view configuration, specify a template
asset specification as the renderer
argument, or
attribute to the view configuration of a view
callable. Then return a dictionary from that view callable. The
dictionary items returned by the view callable will be made available
to the renderer template as top-level names.
The association of a template as a renderer for a view configuration makes it possible to replace code within a view callable that handles the rendering of a template.
Here's an example of using a view_config
decorator to specify a view configuration that names a
template renderer:
1 2 3 4 5 | from pyramid.view import view_config
@view_config(renderer='templates/foo.pt')
def my_view(request):
return {'foo':1, 'bar':2}
|
Note
You do not need to supply the request
value as a key
in the dictionary result returned from a renderer-configured view
callable. Pyramid automatically supplies this value for
you so that the "most correct" system values are provided to
the renderer.
Warning
The renderer
argument to the @view_config
configuration decorator
shown above is the template path. In the example above, the path
templates/foo.pt
is relative. Relative to what, you ask? Because
we're using a Chameleon renderer, it means "relative to the directory in
which the file which defines the view configuration lives". In this case,
this is the directory containing the file that defines the my_view
function. View-configuration-relative asset specifications work only
in Chameleon, not in Mako templates.
Similar renderer configuration can be done imperatively. See Writing View Callables Which Use a Renderer.
See also
See also Built-In Renderers.
Although a renderer path is usually just a simple relative pathname, a path
named as a renderer can be absolute, starting with a slash on UNIX or a drive
letter prefix on Windows. The path can alternately be an asset
specification in the form some.dotted.package_name:relative/path
, making
it possible to address template assets which live in another package.
Not just any template from any arbitrary templating system may be used as a renderer. Bindings must exist specifically for Pyramid to use a templating language template as a renderer.
By default, views rendered via a template renderer return a Response
object which has a status code of 200 OK
, and a content-type of
text/html
. To vary attributes of the response of a view that uses a
renderer, such as the content-type, headers, or status attributes, you must
use the API of the pyramid.response.Response
object exposed as
request.response
within the view before returning the dictionary. See
Varying Attributes of Rendered Responses for more information.
The same set of system values are provided to templates rendered via a renderer view configuration as those provided to templates rendered imperatively. See System Values Used During Rendering.
Debugging Templates¶
A NameError
exception resulting from rendering a template with an
undefined variable (e.g. ${wrong}
) might end up looking like this:
RuntimeError: Caught exception rendering template.
- Expression: ``wrong``
- Filename: /home/fred/env/proj/proj/templates/mytemplate.pt
- Arguments: renderer_name: proj:templates/mytemplate.pt
template: <PageTemplateFile - at 0x1d2ecf0>
xincludes: <XIncludes - at 0x1d3a130>
request: <Request - at 0x1d2ecd0>
project: proj
macros: <Macros - at 0x1d3aed0>
context: <MyResource None at 0x1d39130>
view: <function my_view at 0x1d23570>
NameError: wrong
The output tells you which template the error occurred in, as well as displaying the arguments passed to the template itself.
Automatically Reloading Templates¶
It's often convenient to see changes you make to a template file appear immediately without needing to restart the application process. Pyramid allows you to configure your application development environment so that a change to a template will be automatically detected, and the template will be reloaded on the next rendering.
Warning
Auto-template-reload behavior is not recommended for production sites as it slows rendering slightly; it's usually only desirable during development.
In order to turn on automatic reloading of templates, you can use an environment variable, or a configuration file setting.
To use an environment variable, start your application under a shell
using the PYRAMID_RELOAD_TEMPLATES
operating system environment
variable set to 1
, For example:
$ PYRAMID_RELOAD_TEMPLATES=1 $VENV/bin/pserve myproject.ini
To use a setting in the application .ini
file for the same
purpose, set the pyramid.reload_templates
key to true
within the
application's configuration section, e.g.:
1 2 3 | [app:main]
use = egg:MyProject
pyramid.reload_templates = true
|
Available Add-On Template System Bindings¶
The Pylons Project maintains several packages providing bindings to different templating languages including the following:
Template Language | Pyramid Bindings | Default Extensions |
---|---|---|
Chameleon | pyramid_chameleon | .pt, .txt |
Jinja2 | pyramid_jinja2 | .jinja2 |
Mako | pyramid_mako | .mak, .mako |