summaryrefslogtreecommitdiff
path: root/docs/source/templates.rst
blob: 271d815741e96a6cb0949f67647025f08b1c88b7 (plain)
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
.. _templates:

Templating in Pecan 
===================

Pecan supports a variety of templating engines out of the box, and also provides
the ability to easily add support for new template engines. Currently, Pecan 
supports the following templating engines:

 * `Mako <http://www.makotemplates.org/>`_
 * `Genshi <http://genshi.edgewall.org/>`_
 * `Kajiki <http://kajiki.pythonisito.com/>`_
 * `Jinja2 <http://jinja.pocoo.org/>`_
 * `JSON`

The default template system is `mako`, but can be configured by passing the 
``default_renderer`` key in your application's configuration::
    
    app = {
        'default_renderer' : 'kajiki',
        # ...
    }

The available renderer type strings are ``mako``, ``genshi``, ``kajiki``,
``jinja``, and ``json``.


Using Template Renderers
------------------------

:ref:`pecan_decorators` defines a decorator called ``@expose``, which is used
to flag a method as a public controller. The ``@expose`` decorator takes
a variety of parameters, including a ``template`` argument, which is the path
to the template file to use for that controller. ``@expose`` will use the
default template engine unless the path is prefixed by another renderer name::

    class MyController(object):
        @expose('path/to/mako/template.html')
        def index(self):
            return dict(message='I am a mako template')

        @expose('kajiki:path/to/kajiki/template.html')
        def my_controller(self):
            return dict(message='I am a kajiki template')

For more information on the expose decorator, refer to :ref:`pecan_decorators`,
:ref:`pecan_core`, and :ref:`routing`.


Template Overrides and Manual Rendering
---------------------------------------

The :ref:`pecan_core` module contains two useful helper functions related to
templating. The first is ``override_template``, which allows you to overrides
which template is used in your controller, and the second is ``render``, which
allows you to manually render output using the Pecan templating framework.

To use ``override_template``, simply call it within the body of your controller

::

    class MyController(object):
        @expose('template_one.html')
        def index(self):
            # ...
            override_template('template_two.html')
            return dict(message='I will now render with template_two.html')

The ``render`` helper is also quite simple to use::

    @expose()
    def controller(self):
        return render('my_template.html', dict(message='I am the namespace'))


The JSON Renderer
-----------------

Pecan also provides a `JSON` renderer, e.g.,  ``@expose('json')``. For 
more information on using `JSON` in Pecan, please refer to :ref:`jsonify` and
:ref:`pecan_jsonify`.


Defining Custom Renderers
-------------------------

To define a custom renderer, you can create a class that follows a simple
protocol::

    class MyRenderer(object):
        def __init__(self, path, extra_vars):
            '''
            Your renderer is provided with a path to templates,
            as configured by your application, and any extra 
            template variables, also as configured
            '''
            pass
    
        def render(self, template_path, namespace):
            '''
            Lookup the template based on the path, and render 
            your output based upon the supplied namespace 
            dictionary, as returned from the controller.
            '''
            return str(namespace)


To enable your custom renderer, you can define a ``custom_renderers`` key in
your application's configuration::

    app = {
        'custom_renderers' : {
            'my_renderer' : MyRenderer
        },
        # ...
    }