# -*- coding: utf-8 -*- <%inherit file="content_layout.html"/> <%page args="toc, extension, paged"/> <%namespace name="formatting" file="formatting.html"/> <%namespace name="nav" file="nav.html"/> <%def name="title()">Mako Documentation - Basic Usage <%! filename = 'usage' %> ## This file is generated. Edit the .txt files instead of this one. <%call expr="formatting.section(path='usage',paged=paged,extension=extension,toc=toc)">

This section describes the Python API for Mako templates. If you are using Mako within a web framework such as Pylons, the work of integrating Mako's API is already done for you, in which case you can skip to the next section, <%call expr="nav.toclink(path='syntax',paged=paged,extension=extension,toc=toc)">.

The most basic way to create a template and render it is through the <%text filter='h'>Template class:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template mytemplate = Template("hello world!") print mytemplate.render()

Above, the text argument to <%text filter='h'>Template is compiled into a Python module representation. This module contains a function called <%text filter='h'>render_body(), which produces the output of the template. When <%text filter='h'>mytemplate.render() is called, Mako sets up a runtime environment for the template and calls the <%text filter='h'>render_body() function, capturing the output into a buffer and returning its string contents.

The code inside the <%text filter='h'>render_body() function has access to a namespace of variables. You can specify these variables by sending them as additional keyword arguments to the <%text filter='h'>render() method:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template mytemplate = Template("hello, ${name}!") print mytemplate.render(name="jack")

The <%text filter='h'>template.render() method calls upon Mako to create a <%text filter='h'>Context object, which stores all the variable names accessible to the template and also stores a buffer used to capture output. You can create this <%text filter='h'>Context yourself and have the template render with it, using the <%text filter='h'>render_context method:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template from mako.runtime import Context from StringIO import StringIO mytemplate = Template("hello, ${name}!") buf = StringIO() ctx = Context(buf, name="jack") mytemplate.render_context(ctx) print buf.getvalue() <%call expr="formatting.section(path='usage_file',paged=paged,extension=extension,toc=toc)">

A <%text filter='h'>Template can also load its template source code from a file, using the <%text filter='h'>filename keyword argument:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt') print mytemplate.render()

For improved performance, a <%text filter='h'>Template which is loaded from a file can also cache the source code to its generated module on the filesystem as a regular Python module file (i.e. a .py file). To do this, just add the <%text filter='h'>module_directory argument to the template:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template mytemplate = Template(filename='/docs/mytmpl.txt', module_directory='/tmp/mako_modules') print mytemplate.render()

When the above code is rendered, a file <%text filter='h'>/tmp/mako_modules/docs/mytmpl.txt.py is created containing the source code for the module. The next time a <%text filter='h'>Template with the same arguments is created, this module file will be automatically re-used.

<%call expr="formatting.section(path='usage_lookup',paged=paged,extension=extension,toc=toc)">

All of the examples thus far have dealt with the usage of a single <%text filter='h'>Template object. If the code within those templates tries to locate another template resource, it will need some way to find them, using simple URI strings. For this need, the resolution of other templates from within a template is accomplished by the <%text filter='h'>TemplateLookup class. This class is constructed given a list of directories in which to search for templates, as well as keyword arguments that will be passed to the <%text filter='h'>Template objects it creates.

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs']) mytemplate = Template("""<%include file="header.txt"/> hello world!""", lookup=mylookup)

Above, we created a textual template which includes the file <%text filter='h'>header.txt. In order for it to have somewhere to look for <%text filter='h'>header.txt, we passed a <%text filter='h'>TemplateLookup object to it, which will search in the directory <%text filter='h'>/docs for the file <%text filter='h'>header.txt.

Usually, an application will store most or all of its templates as text files on the filesystem. So far, all of our examples have been a little bit contrived in order to illustrate the basic concepts. But a real application would get most or all of its templates directly from the <%text filter='h'>TemplateLookup, using the aptly named <%text filter='h'>get_template method, which accepts the URI of the desired template:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules') def serve_template(templatename, **kwargs): mytemplate = mylookup.get_template(templatename) print mytemplate.render(**kwargs)

In the example above, we create a <%text filter='h'>TemplateLookup which will look for templates in the <%text filter='h'>/docs directory, and will store generated module files in the <%text filter='h'>/tmp/mako_modules directory. The lookup locates templates by appending the given URI to each of its search directories; so if you gave it a URI of <%text filter='h'>/etc/beans/info.txt, it would search for the file <%text filter='h'>/docs/etc/beans/info.txt, else raise a <%text filter='h'>TopLevelNotFound exception, which is a custom Mako exception.

When the lookup locates templates, it will also assign a <%text filter='h'>uri property to the <%text filter='h'>Template which is the uri passed to the <%text filter='h'>get_template() call. <%text filter='h'>Template uses this uri to calculate the name of its module file. So in the above example, a <%text filter='h'>templatename argument of <%text filter='h'>/etc/beans/info.txt will create a module file <%text filter='h'>/tmp/mako_modules/etc/beans/info.txt.py.

<%call expr="formatting.section(path='usage_lookup_size',paged=paged,extension=extension,toc=toc)">

The <%text filter='h'>TemplateLookup also serves the important need of caching a fixed set of templates in memory at a given time, so that successive uri lookups do not result in full template compilations and/or module reloads on each request. By default, the <%text filter='h'>TemplateLookup size is unbounded. You can specify a fixed size using the <%text filter='h'>collection_size argument:

<%call expr="formatting.code(syntaxtype='python')"><%text> mylookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules', collection_size=500)

The above lookup will continue to load templates into memory until it reaches a count of around 500. At that point, it will clean out a certain percentage of templates using a least recently used scheme.

<%call expr="formatting.section(path='usage_lookup_checks',paged=paged,extension=extension,toc=toc)">

Another important flag on <%text filter='h'>TemplateLookup is <%text filter='h'>filesystem_checks. This defaults to <%text filter='h'>True, and says that each time a template is returned by the <%text filter='h'>get_template() method, the revision time of the original template file is checked against the last time the template was loaded, and if the file is newer will reload its contents and recompile the template. On a production system, setting <%text filter='h'>filesystem_checks to <%text filter='h'>False can afford a small to moderate performance increase (depending on the type of filesystem used).

<%call expr="formatting.section(path='usage_using',paged=paged,extension=extension,toc=toc)">

Both <%text filter='h'>Template and <%text filter='h'>TemplateLookup accept <%text filter='h'>output_encoding and <%text filter='h'>encoding_errors parameters which can be used to encode the output in any Python supported codec:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.template import Template from mako.lookup import TemplateLookup mylookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace') mytemplate = mylookup.get_template("foo.txt") print mytemplate.render()

When using Python 3, the <%text filter='h'>render() method will return a <%text filter='h'>bytes object, if <%text filter='h'>output_encoding is set. Otherwise it returns a <%text filter='h'>string.

Additionally, the <%text filter='h'>render_unicode() method exists which will return the template output as a Python <%text filter='h'>unicode object, or in Python 3 a <%text filter='h'>string:

<%call expr="formatting.code(syntaxtype='python')"><%text> print mytemplate.render_unicode()

The above method disregards the output encoding keyword argument; you can encode yourself by saying:

<%call expr="formatting.code(syntaxtype='python')"><%text> print mytemplate.render_unicode().encode('utf-8', 'replace')

Note that Mako's ability to return data in any encoding and/or <%text filter='h'>unicode implies that the underlying output stream of the template is a Python unicode object. This behavior is described fully in <%call expr="nav.toclink(path='unicode',paged=paged,extension=extension,toc=toc)">.

<%call expr="formatting.section(path='usage_handling',paged=paged,extension=extension,toc=toc)">

Template exceptions can occur in two distinct places. One is when you lookup, parse and compile the template, the other is when you run the template. Within the running of a template, exceptions are thrown normally from whatever Python code originated the issue. Mako has its own set of exception classes which mostly apply to the lookup and lexer/compiler stages of template construction. Mako provides some library routines that can be used to help provide Mako-specific information about any exception's stack trace, as well as formatting the exception within textual or HTML format. In all cases, the main value of these handlers is that of converting Python filenames, line numbers, and code samples into Mako template filenames, line numbers, and code samples. All lines within a stack trace which correspond to a Mako template module will be converted to be against the originating template file.

To format exception traces, the <%text filter='h'>text_error_template and <%text filter='h'>html_error_template functions are provided. They make usage of <%text filter='h'>sys.exc_info() to get at the most recently thrown exception. Usage of these handlers usually looks like:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.text_error_template().render()

Or for the HTML render function:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako import exceptions try: template = lookup.get_template(uri) print template.render() except: print exceptions.html_error_template().render()

The <%text filter='h'>html_error_template template accepts two options: specifying <%text filter='h'>full=False causes only a section of an HTML document to be rendered. Specifying <%text filter='h'>css=False will disable the default stylesheet from being rendered.

E.g.:

<%call expr="formatting.code()"><%text> print exceptions.html_error_template().render(full=False)

The HTML render function is also available built-in to <%text filter='h'>Template using the <%text filter='h'>format_exceptions flag. In this case, any exceptions raised within the render stage of the template will result in the output being substituted with the output of <%text filter='h'>html_error_template.

<%call expr="formatting.code(syntaxtype='python')"><%text> template = Template(filename="/foo/bar", format_exceptions=True) print template.render()

Note that the compile stage of the above template occurs when you construct the <%text filter='h'>Template itself, and no output stream is defined. Therefore exceptions which occur within the lookup/parse/compile stage will not be handled and will propagate normally. While the pre-render traceback usually will not include any Mako-specific lines anyway, it will mean that exceptions which occur previous to rendering and those which occur within rendering will be handled differently...so the <%text filter='h'>try/except patterns described previously are probably of more general use.

The underlying object used by the error template functions is the <%text filter='h'>RichTraceback object. This object can also be used directly to provide custom error views. Here's an example usage which describes its general API:

<%call expr="formatting.code(syntaxtype='python')"><%text> from mako.exceptions import RichTraceback try: template = lookup.get_template(uri) print template.render() except: traceback = RichTraceback() for (filename, lineno, function, line) in traceback.traceback: print "File %s, line %s, in %s" % (filename, lineno, function) print line, "\n" print "%s: %s" % (str(traceback.error.__class__.__name__), traceback.error)

Further information about <%text filter='h'>RichTraceback is available within the module-level documentation for <%text filter='h'>mako.exceptions.

<%call expr="formatting.section(path='usage_common',paged=paged,extension=extension,toc=toc)">

The Mako distribution includes a little bit of helper code for the purpose of using Mako in some popular web framework scenarios. This is a brief description of whats included.

<%call expr="formatting.section(path='usage_common_turbogears/pylons',paged=paged,extension=extension,toc=toc)">

The standard plugin methodology used by Turbogears as well as Pylons is included in the module <%text filter='h'>mako.ext.turbogears, using the <%text filter='h'>TGPlugin class. This is also a setuptools entrypoint under the heading <%text filter='h'>python.templating.engines with the name <%text filter='h'>mako.

<%call expr="formatting.section(path='usage_common_wsgi',paged=paged,extension=extension,toc=toc)">

A sample WSGI application is included in the distrubution in the file <%text filter='h'>examples/wsgi/run_wsgi.py. This runner is set up to pull files from a <%text filter='h'>templates as well as an <%text filter='h'>htdocs directory and includes a rudimental two-file layout. The WSGI runner acts as a fully functional standalone web server, using <%text filter='h'>wsgiutils to run itself, and propagates GET and POST arguments from the request into the <%text filter='h'>Context, can serve images, css files and other kinds of files, and also displays errors using Mako's included exception-handling utilities.

<%call expr="formatting.section(path='usage_common_pygments',paged=paged,extension=extension,toc=toc)">

A Pygments-compatible syntax highlighting module is included under <%text filter='h'>mako.ext.pygmentplugin. This module is used in the generation of Mako documentation and also contains various setuptools entry points under the heading <%text filter='h'>pygments.lexers, including <%text filter='h'>mako, <%text filter='h'>html+mako, <%text filter='h'>xml+mako (see the <%text filter='h'>setup.py file for all the entry points).

<%call expr="formatting.section(path='usage_common_babel',paged=paged,extension=extension,toc=toc)">

Mako provides support for extracting gettext messages from templates via a Babel extractor entry point under <%text filter='h'>mako.ext.babelplugin.

Gettext messages are extracted from all Python code sections, even the more obscure ones such as <%call expr="nav.toclink(path='syntax_control',paged=paged,description='control structures',extension=extension,toc=toc)">, <%call expr="nav.toclink(path='defs',paged=paged,description='def tag function declarations',extension=extension,toc=toc)">, <%call expr="nav.toclink(path='defs_defswithcontent',paged=paged,description='call tag exprs',extension=extension,toc=toc)"> and even <%call expr="nav.toclink(path='syntax_tags_page',paged=paged,description='page tag args',extension=extension,toc=toc)">.

Translator comments may also be extracted from Mako templates when a comment tag is specified to Babel (such as with the -c option).

For example, a project '<%text filter='h'>myproj' contains the following Mako template at myproj/myproj/templates/name.html:

<%call expr="formatting.code()"><%text>
Name: ## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. ${_('Francois Pinard')}

To extract gettext messages from this template the project needs a Mako section in its Babel Extraction Method Mapping file (typically located at myproj/babel.cfg):

<%call expr="formatting.code(syntaxtype='ini')"><%text> # Extraction from Python source files [python: myproj/**.py] # Extraction from Mako templates [mako: myproj/templates/**.html] input_encoding = utf-8

The Mako extractor supports an optional <%text filter='h'>input_encoding parameter specifying the encoding of the templates (identical to <%text filter='h'>Template/<%text filter='h'>TemplateLookup's <%text filter='h'>input_encoding parameter).

Invoking Babel's extractor at the command line in the project's root directory:

<%call expr="formatting.code()"><%text>myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .

Will output a gettext catalog to stdout including the following:

<%call expr="formatting.code()"><%text>#. TRANSLATORS: This is a proper name. See the gettext #. manual, section Names. #: myproj/templates/name.html:5 msgid "Francois Pinard" msgstr ""

This is only a basic example: Babel can be invoked from setup.py and its command line options specified in the accompanying setup.cfg via Babel Distutils/Setuptools Integration.

Comments must immediately precede a gettext message to be extracted. In the following case the TRANSLATORS: comment would not have been extracted:

<%call expr="formatting.code()"><%text>
## TRANSLATORS: This is a proper name. See the gettext ## manual, section Names. Name: ${_('Francois Pinard')}

See the Babel User Guide for more information.