1.. _usage_toplevel:
2
3=====
4Usage
5=====
6
7Basic Usage
8===========
9
10This section describes the Python API for Mako templates. If you
11are using Mako within a web framework such as Pylons, the work
12of integrating Mako's API is already done for you, in which case
13you can skip to the next section, :ref:`syntax_toplevel`.
14
15The most basic way to create a template and render it is through
16the :class:`.Template` class:
17
18.. sourcecode:: python
19
20    from mako.template import Template
21
22    mytemplate = Template("hello world!")
23    print(mytemplate.render())
24
25Above, the text argument to :class:`.Template` is **compiled** into a
26Python module representation. This module contains a function
27called ``render_body()``, which produces the output of the
28template. When ``mytemplate.render()`` is called, Mako sets up a
29runtime environment for the template and calls the
30``render_body()`` function, capturing the output into a buffer and
31returning its string contents.
32
33
34The code inside the ``render_body()`` function has access to a
35namespace of variables. You can specify these variables by
36sending them as additional keyword arguments to the :meth:`~.Template.render`
37method:
38
39.. sourcecode:: python
40
41    from mako.template import Template
42
43    mytemplate = Template("hello, ${name}!")
44    print(mytemplate.render(name="jack"))
45
46The :meth:`~.Template.render` method calls upon Mako to create a
47:class:`.Context` object, which stores all the variable names accessible
48to the template and also stores a buffer used to capture output.
49You can create this :class:`.Context` yourself and have the template
50render with it, using the :meth:`~.Template.render_context` method:
51
52.. sourcecode:: python
53
54    from mako.template import Template
55    from mako.runtime import Context
56    from io import StringIO
57
58    mytemplate = Template("hello, ${name}!")
59    buf = StringIO()
60    ctx = Context(buf, name="jack")
61    mytemplate.render_context(ctx)
62    print(buf.getvalue())
63
64Using File-Based Templates
65==========================
66
67A :class:`.Template` can also load its template source code from a file,
68using the ``filename`` keyword argument:
69
70.. sourcecode:: python
71
72    from mako.template import Template
73
74    mytemplate = Template(filename='/docs/mytmpl.txt')
75    print(mytemplate.render())
76
77For improved performance, a :class:`.Template` which is loaded from a
78file can also cache the source code to its generated module on
79the filesystem as a regular Python module file (i.e. a ``.py``
80file). To do this, just add the ``module_directory`` argument to
81the template:
82
83.. sourcecode:: python
84
85    from mako.template import Template
86
87    mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules')
88    print(mytemplate.render())
89
90When the above code is rendered, a file
91``/tmp/mako_modules/docs/mytmpl.txt.py`` is created containing the
92source code for the module. The next time a :class:`.Template` with the
93same arguments is created, this module file will be
94automatically re-used.
95
96.. _usage_templatelookup:
97
98Using ``TemplateLookup``
99========================
100
101All of the examples thus far have dealt with the usage of a
102single :class:`.Template` object. If the code within those templates
103tries to locate another template resource, it will need some way
104to find them, using simple URI strings. For this need, the
105resolution of other templates from within a template is
106accomplished by the :class:`.TemplateLookup` class. This class is
107constructed given a list of directories in which to search for
108templates, as well as keyword arguments that will be passed to
109the :class:`.Template` objects it creates:
110
111.. sourcecode:: python
112
113    from mako.template import Template
114    from mako.lookup import TemplateLookup
115
116    mylookup = TemplateLookup(directories=['/docs'])
117    mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)
118
119Above, we created a textual template which includes the file
120``"header.txt"``. In order for it to have somewhere to look for
121``"header.txt"``, we passed a :class:`.TemplateLookup` object to it, which
122will search in the directory ``/docs`` for the file ``"header.txt"``.
123
124Usually, an application will store most or all of its templates
125as text files on the filesystem. So far, all of our examples
126have been a little bit contrived in order to illustrate the
127basic concepts. But a real application would get most or all of
128its templates directly from the :class:`.TemplateLookup`, using the
129aptly named :meth:`~.TemplateLookup.get_template` method, which accepts the URI of the
130desired template:
131
132.. sourcecode:: python
133
134    from mako.template import Template
135    from mako.lookup import TemplateLookup
136
137    mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')
138
139    def serve_template(templatename, **kwargs):
140        mytemplate = mylookup.get_template(templatename)
141        print(mytemplate.render(**kwargs))
142
143In the example above, we create a :class:`.TemplateLookup` which will
144look for templates in the ``/docs`` directory, and will store
145generated module files in the ``/tmp/mako_modules`` directory. The
146lookup locates templates by appending the given URI to each of
147its search directories; so if you gave it a URI of
148``/etc/beans/info.txt``, it would search for the file
149``/docs/etc/beans/info.txt``, else raise a :class:`.TopLevelNotFound`
150exception, which is a custom Mako exception.
151
152When the lookup locates templates, it will also assign a ``uri``
153property to the :class:`.Template` which is the URI passed to the
154:meth:`~.TemplateLookup.get_template()` call. :class:`.Template` uses this URI to calculate the
155name of its module file. So in the above example, a
156``templatename`` argument of ``/etc/beans/info.txt`` will create a
157module file ``/tmp/mako_modules/etc/beans/info.txt.py``.
158
159Setting the Collection Size
160---------------------------
161
162The :class:`.TemplateLookup` also serves the important need of caching a
163fixed set of templates in memory at a given time, so that
164successive URI lookups do not result in full template
165compilations and/or module reloads on each request. By default,
166the :class:`.TemplateLookup` size is unbounded. You can specify a fixed
167size using the ``collection_size`` argument:
168
169.. sourcecode:: python
170
171    mylookup = TemplateLookup(directories=['/docs'],
172                    module_directory='/tmp/mako_modules', collection_size=500)
173
174The above lookup will continue to load templates into memory
175until it reaches a count of around 500. At that point, it will
176clean out a certain percentage of templates using a least
177recently used scheme.
178
179Setting Filesystem Checks
180-------------------------
181
182Another important flag on :class:`.TemplateLookup` is
183``filesystem_checks``. This defaults to ``True``, and says that each
184time a template is returned by the :meth:`~.TemplateLookup.get_template()` method, the
185revision time of the original template file is checked against
186the last time the template was loaded, and if the file is newer
187will reload its contents and recompile the template. On a
188production system, setting ``filesystem_checks`` to ``False`` can
189afford a small to moderate performance increase (depending on
190the type of filesystem used).
191
192.. _usage_unicode:
193
194Using Unicode and Encoding
195==========================
196
197Both :class:`.Template` and :class:`.TemplateLookup` accept ``output_encoding``
198and ``encoding_errors`` parameters which can be used to encode the
199output in any Python supported codec:
200
201.. sourcecode:: python
202
203    from mako.template import Template
204    from mako.lookup import TemplateLookup
205
206    mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
207
208    mytemplate = mylookup.get_template("foo.txt")
209    print(mytemplate.render())
210
211When using Python 3, the :meth:`~.Template.render` method will return a ``bytes``
212object, **if** ``output_encoding`` is set. Otherwise it returns a
213``string``.
214
215Additionally, the :meth:`~.Template.render_unicode()` method exists which will
216return the template output as a Python ``unicode`` object, or in
217Python 3 a ``string``:
218
219.. sourcecode:: python
220
221    print(mytemplate.render_unicode())
222
223The above method disregards the output encoding keyword
224argument; you can encode yourself by saying:
225
226.. sourcecode:: python
227
228    print(mytemplate.render_unicode().encode('utf-8', 'replace'))
229
230Note that Mako's ability to return data in any encoding and/or
231``unicode`` implies that the underlying output stream of the
232template is a Python unicode object. This behavior is described
233fully in :ref:`unicode_toplevel`.
234
235.. _handling_exceptions:
236
237Handling Exceptions
238===================
239
240Template exceptions can occur in two distinct places. One is
241when you **lookup, parse and compile** the template, the other
242is when you **run** the template. Within the running of a
243template, exceptions are thrown normally from whatever Python
244code originated the issue. Mako has its own set of exception
245classes which mostly apply to the lookup and lexer/compiler
246stages of template construction. Mako provides some library
247routines that can be used to help provide Mako-specific
248information about any exception's stack trace, as well as
249formatting the exception within textual or HTML format. In all
250cases, the main value of these handlers is that of converting
251Python filenames, line numbers, and code samples into Mako
252template filenames, line numbers, and code samples. All lines
253within a stack trace which correspond to a Mako template module
254will be converted to be against the originating template file.
255
256To format exception traces, the :func:`.text_error_template` and
257:func:`.html_error_template` functions are provided. They make usage of
258``sys.exc_info()`` to get at the most recently thrown exception.
259Usage of these handlers usually looks like:
260
261.. sourcecode:: python
262
263    from mako import exceptions
264
265    try:
266        template = lookup.get_template(uri)
267        print(template.render())
268    except:
269        print(exceptions.text_error_template().render())
270
271Or for the HTML render function:
272
273.. sourcecode:: python
274
275    from mako import exceptions
276
277    try:
278        template = lookup.get_template(uri)
279        print(template.render())
280    except:
281        print(exceptions.html_error_template().render())
282
283The :func:`.html_error_template` template accepts two options:
284specifying ``full=False`` causes only a section of an HTML
285document to be rendered. Specifying ``css=False`` will disable the
286default stylesheet from being rendered.
287
288E.g.:
289
290.. sourcecode:: python
291
292    print(exceptions.html_error_template().render(full=False))
293
294The HTML render function is also available built-in to
295:class:`.Template` using the ``format_exceptions`` flag. In this case, any
296exceptions raised within the **render** stage of the template
297will result in the output being substituted with the output of
298:func:`.html_error_template`:
299
300.. sourcecode:: python
301
302    template = Template(filename="/foo/bar", format_exceptions=True)
303    print(template.render())
304
305Note that the compile stage of the above template occurs when
306you construct the :class:`.Template` itself, and no output stream is
307defined. Therefore exceptions which occur within the
308lookup/parse/compile stage will not be handled and will
309propagate normally. While the pre-render traceback usually will
310not include any Mako-specific lines anyway, it will mean that
311exceptions which occur previous to rendering and those which
312occur within rendering will be handled differently... so the
313``try``/``except`` patterns described previously are probably of more
314general use.
315
316The underlying object used by the error template functions is
317the :class:`.RichTraceback` object. This object can also be used
318directly to provide custom error views. Here's an example usage
319which describes its general API:
320
321.. sourcecode:: python
322
323    from mako.exceptions import RichTraceback
324
325    try:
326        template = lookup.get_template(uri)
327        print(template.render())
328    except:
329        traceback = RichTraceback()
330        for (filename, lineno, function, line) in traceback.traceback:
331            print("File %s, line %s, in %s" % (filename, lineno, function))
332            print(line, "\n")
333        print("%s: %s" % (str(traceback.error.__class__.__name__), traceback.error))
334
335Common Framework Integrations
336=============================
337
338The Mako distribution includes a little bit of helper code for
339the purpose of using Mako in some popular web framework
340scenarios. This is a brief description of what's included.
341
342WSGI
343----
344
345A sample WSGI application is included in the distribution in the
346file ``examples/wsgi/run_wsgi.py``. This runner is set up to pull
347files from a `templates` as well as an `htdocs` directory and
348includes a rudimental two-file layout. The WSGI runner acts as a
349fully functional standalone web server, using ``wsgiutils`` to run
350itself, and propagates GET and POST arguments from the request
351into the :class:`.Context`, can serve images, CSS files and other kinds
352of files, and also displays errors using Mako's included
353exception-handling utilities.
354
355Pygments
356--------
357
358A `Pygments <https://pygments.org/>`_-compatible syntax
359highlighting module is included under :mod:`mako.ext.pygmentplugin`.
360This module is used in the generation of Mako documentation and
361also contains various `setuptools` entry points under the heading
362``pygments.lexers``, including ``mako``, ``html+mako``, ``xml+mako``
363(see the ``setup.py`` file for all the entry points).
364
365Babel
366-----
367
368Mako provides support for extracting `gettext` messages from
369templates via a `Babel`_ extractor
370entry point under ``mako.ext.babelplugin``.
371
372`Gettext` messages are extracted from all Python code sections,
373including those of control lines and expressions embedded
374in tags.
375
376`Translator
377comments <http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation>`_
378may also be extracted from Mako templates when a comment tag is
379specified to `Babel`_ (such as with
380the ``-c`` option).
381
382For example, a project ``"myproj"`` contains the following Mako
383template at ``myproj/myproj/templates/name.html``:
384
385.. sourcecode:: mako
386
387    <div id="name">
388      Name:
389      ## TRANSLATORS: This is a proper name. See the gettext
390      ## manual, section Names.
391      ${_('Francois Pinard')}
392    </div>
393
394To extract gettext messages from this template the project needs
395a Mako section in its `Babel Extraction Method Mapping
396file <http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration>`_
397(typically located at ``myproj/babel.cfg``):
398
399.. sourcecode:: cfg
400
401    # Extraction from Python source files
402
403    [python: myproj/**.py]
404
405    # Extraction from Mako templates
406
407    [mako: myproj/templates/**.html]
408    input_encoding = utf-8
409
410The Mako extractor supports an optional ``input_encoding``
411parameter specifying the encoding of the templates (identical to
412:class:`.Template`/:class:`.TemplateLookup`'s ``input_encoding`` parameter).
413
414Invoking `Babel`_'s extractor at the
415command line in the project's root directory:
416
417.. sourcecode:: sh
418
419    myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
420
421will output a `gettext` catalog to `stdout` including the following:
422
423.. sourcecode:: pot
424
425    #. TRANSLATORS: This is a proper name. See the gettext
426    #. manual, section Names.
427    #: myproj/templates/name.html:5
428    msgid "Francois Pinard"
429    msgstr ""
430
431This is only a basic example:
432`Babel`_ can be invoked from ``setup.py``
433and its command line options specified in the accompanying
434``setup.cfg`` via `Babel Distutils/Setuptools
435Integration <http://babel.edgewall.org/wiki/Documentation/setup.html>`_.
436
437Comments must immediately precede a `gettext` message to be
438extracted. In the following case the ``TRANSLATORS:`` comment would
439not have been extracted:
440
441.. sourcecode:: mako
442
443    <div id="name">
444      ## TRANSLATORS: This is a proper name. See the gettext
445      ## manual, section Names.
446      Name: ${_('Francois Pinard')}
447    </div>
448
449See the `Babel User
450Guide <http://babel.edgewall.org/wiki/Documentation/index.html>`_
451for more information.
452
453.. _babel: http://babel.edgewall.org/
454
455
456API Reference
457=============
458
459.. autoclass:: mako.template.Template
460    :show-inheritance:
461    :members:
462
463.. autoclass:: mako.template.DefTemplate
464    :show-inheritance:
465    :members:
466
467.. autoclass:: mako.lookup.TemplateCollection
468    :show-inheritance:
469    :members:
470
471.. autoclass:: mako.lookup.TemplateLookup
472    :show-inheritance:
473    :members:
474
475.. autoclass:: mako.exceptions.RichTraceback
476    :show-inheritance:
477
478    .. py:attribute:: error
479
480       the exception instance.
481
482    .. py:attribute:: message
483
484       the exception error message as unicode.
485
486    .. py:attribute:: source
487
488       source code of the file where the error occurred.
489       If the error occurred within a compiled template,
490       this is the template source.
491
492    .. py:attribute:: lineno
493
494       line number where the error occurred.  If the error
495       occurred within a compiled template, the line number
496       is adjusted to that of the template source.
497
498    .. py:attribute:: records
499
500       a list of 8-tuples containing the original
501       python traceback elements, plus the
502       filename, line number, source line, and full template source
503       for the traceline mapped back to its originating source
504       template, if any for that traceline (else the fields are ``None``).
505
506    .. py:attribute:: reverse_records
507
508       the list of records in reverse
509       traceback -- a list of 4-tuples, in the same format as a regular
510       python traceback, with template-corresponding
511       traceback records replacing the originals.
512
513    .. py:attribute:: reverse_traceback
514
515       the traceback list in reverse.
516
517.. autofunction:: mako.exceptions.html_error_template
518
519.. autofunction:: mako.exceptions.text_error_template
520