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, Syntax.
The most basic way to create a template and render it is through
the Template
class:
from mako.template import Template
mytemplate = Template("hello world!")
print(mytemplate.render())
Above, the text argument to Template
is compiled into a
Python module representation. This module contains a function
called render_body()
, which produces the output of the
template. When mytemplate.render()
is called, Mako sets up a
runtime environment for the template and calls the
render_body()
function, capturing the output into a buffer and
returning its string contents.
The code inside the render_body()
function has access to a
namespace of variables. You can specify these variables by
sending them as additional keyword arguments to the Template.render()
method:
from mako.template import Template
mytemplate = Template("hello, ${name}!")
print(mytemplate.render(name="jack"))
The Template.render()
method calls upon Mako to create a
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 Context
yourself and have the template
render with it, using the Template.render_context()
method:
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())
A Template
can also load its template source code from a file,
using the filename
keyword argument:
from mako.template import Template
mytemplate = Template(filename='/docs/mytmpl.txt')
print(mytemplate.render())
For improved performance, a 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 module_directory
argument to
the template:
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
/tmp/mako_modules/docs/mytmpl.txt.py
is created containing the
source code for the module. The next time a Template
with the
same arguments is created, this module file will be
automatically re-used.
TemplateLookup
¶All of the examples thus far have dealt with the usage of a
single 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 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 Template
objects it creates:
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
"header.txt"
. In order for it to have somewhere to look for
"header.txt"
, we passed a TemplateLookup
object to it, which
will search in the directory /docs
for the file "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 TemplateLookup
, using the
aptly named TemplateLookup.get_template()
method, which accepts the URI of the
desired template:
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 TemplateLookup
which will
look for templates in the /docs
directory, and will store
generated module files in the /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
/etc/beans/info.txt
, it would search for the file
/docs/etc/beans/info.txt
, else raise a TopLevelNotFound
exception, which is a custom Mako exception.
When the lookup locates templates, it will also assign a uri
property to the Template
which is the URI passed to the
TemplateLookup.get_template()
call. Template
uses this URI to calculate the
name of its module file. So in the above example, a
templatename
argument of /etc/beans/info.txt
will create a
module file /tmp/mako_modules/etc/beans/info.txt.py
.
The 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 TemplateLookup
size is unbounded. You can specify a fixed
size using the collection_size
argument:
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.
Another important flag on TemplateLookup
is
filesystem_checks
. This defaults to True
, and says that each
time a template is returned by the TemplateLookup.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 filesystem_checks
to False
can
afford a small to moderate performance increase (depending on
the type of filesystem used).
Both Template
and TemplateLookup
accept output_encoding
and encoding_errors
parameters which can be used to encode the
output in any Python supported codec:
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 Template.render()
method will return a bytes
object, if output_encoding
is set. Otherwise it returns a
string
.
Additionally, the Template.render_unicode()
method exists which will
return the template output as a Python unicode
object, or in
Python 3 a string
:
print(mytemplate.render_unicode())
The above method disregards the output encoding keyword argument; you can encode yourself by saying:
print(mytemplate.render_unicode().encode('utf-8', 'replace'))
Note that Mako’s ability to return data in any encoding and/or
unicode
implies that the underlying output stream of the
template is a Python unicode object. This behavior is described
fully in The Unicode Chapter.
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_error_template()
and
html_error_template()
functions are provided. They make usage of
sys.exc_info()
to get at the most recently thrown exception.
Usage of these handlers usually looks like:
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:
from mako import exceptions
try:
template = lookup.get_template(uri)
print(template.render())
except:
print(exceptions.html_error_template().render())
The html_error_template()
template accepts two options:
specifying full=False
causes only a section of an HTML
document to be rendered. Specifying css=False
will disable the
default stylesheet from being rendered.
E.g.:
print(exceptions.html_error_template().render(full=False))
The HTML render function is also available built-in to
Template
using the 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
html_error_template()
:
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 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
try
/except
patterns described previously are probably of more
general use.
The underlying object used by the error template functions is
the RichTraceback
object. This object can also be used
directly to provide custom error views. Here’s an example usage
which describes its general API:
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))
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 what’s included.
A sample WSGI application is included in the distribution in the
file examples/wsgi/run_wsgi.py
. This runner is set up to pull
files from a templates as well as an htdocs directory and
includes a rudimental two-file layout. The WSGI runner acts as a
fully functional standalone web server, using wsgiutils
to run
itself, and propagates GET and POST arguments from the request
into the Context
, can serve images, CSS files and other kinds
of files, and also displays errors using Mako’s included
exception-handling utilities.
A Pygments-compatible syntax
highlighting module is included under mako.ext.pygmentplugin
.
This module is used in the generation of Mako documentation and
also contains various setuptools entry points under the heading
pygments.lexers
, including mako
, html+mako
, xml+mako
(see the setup.py
file for all the entry points).
Mako provides support for extracting gettext messages from
templates via a Babel extractor
entry point under mako.ext.babelplugin
.
Gettext messages are extracted from all Python code sections, including those of control lines and expressions embedded in tags.
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 "myproj"
contains the following Mako
template at myproj/myproj/templates/name.html
:
<div id="name">
Name:
## TRANSLATORS: This is a proper name. See the gettext
## manual, section Names.
${_('Francois Pinard')}
</div>
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
):
# 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 input_encoding
parameter specifying the encoding of the templates (identical to
Template
/TemplateLookup
’s input_encoding
parameter).
Invoking Babel’s extractor at the command line in the project’s root directory:
myproj$ pybabel extract -F babel.cfg -c "TRANSLATORS:" .
will output a gettext catalog to stdout including the following:
#. 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:
<div id="name">
## TRANSLATORS: This is a proper name. See the gettext
## manual, section Names.
Name: ${_('Francois Pinard')}
</div>
See the Babel User Guide for more information.
Object Name | Description |
---|---|
Bases: |
|
Provides a template that renders a stack trace in an HTML format, providing an excerpt of code as well as substituting source template filenames, line numbers and code for that of the originating source template, as applicable. |
|
Bases: |
|
Bases: |
|
Bases: |
|
Bases: |
|
text_error_template([lookup]) |
Provides a template that renders a stack trace in a similar format to the Python interpreter, substituting source template filenames, line numbers and code for that of the originating source template, as applicable. |
Bases: object
Represents a compiled template.
Template
includes a reference to the original
template source (via the source
attribute)
as well as the source code of the
generated Python module (i.e. the code
attribute),
as well as a reference to an actual Python module.
Template
is constructed using either a literal string
representing the template text, or a filename representing a filesystem
path to a source file.
Members
code, get_def(), list_defs(), render(), render_context(), render_unicode(), source
text – textual template source. This argument is mutually
exclusive versus the filename
parameter.
filename – filename of the source template. This argument is
mutually exclusive versus the text
parameter.
buffer_filters – string list of filters to be applied
to the output of %def
s which are buffered, cached, or otherwise
filtered, after all filters
defined with the %def
itself have been applied. Allows the
creation of default expression filters that let the output
of return-valued %def
s “opt out” of that filtering via
passing special attributes or objects.
bytestring_passthrough –
When True
, and output_encoding
is
set to None
, and Template.render()
is used to render,
the StringIO or cStringIO buffer will be used instead of the
default “fast” buffer. This allows raw bytestrings in the
output stream, such as in expressions, to pass straight
through to the buffer. This flag is forced
to True
if disable_unicode
is also configured.
New in version 0.4: Added to provide the same behavior as that of the previous series.
cache_args – Dictionary of cache configuration arguments that
will be passed to the CacheImpl
. See Caching.
cache_dir –
Deprecated since version 0.6: Use the 'dir'
argument in the cache_args
dictionary.
See Caching.
cache_enabled – Boolean flag which enables caching of this template. See Caching.
cache_impl – String name of a CacheImpl
caching
implementation to use. Defaults to 'beaker'
.
cache_type –
Deprecated since version 0.6: Use the 'type'
argument in the cache_args
dictionary.
See Caching.
cache_url –
Deprecated since version 0.6: Use the 'url'
argument in the cache_args
dictionary.
See Caching.
default_filters – List of string filter names that will be applied to all expressions. See The default_filters Argument.
disable_unicode – Disables all awareness of Python Unicode objects. See Saying to Heck with It: Disabling the Usage of Unicode Entirely.
enable_loop – When True
, enable the loop
context variable.
This can be set to False
to support templates that may
be making usage of the name “loop
”. Individual templates can
re-enable the “loop” context by placing the directive
enable_loop="True"
inside the <%page>
tag – see
Migrating Legacy Templates that Use the Word “loop”.
encoding_errors – Error parameter passed to encode()
when
string encoding is performed. See Using Unicode and Encoding.
error_handler –
Python callable which is called whenever
compile or runtime exceptions occur. The callable is passed
the current context as well as the exception. If the
callable returns True
, the exception is considered to
be handled, else it is re-raised after the function
completes. Is used to provide custom error-rendering
functions.
See also
Template.include_error_handler
- include-specific
error handler function
format_exceptions – if True
, exceptions which occur during
the render phase of this template will be caught and
formatted into an HTML error page, which then becomes the
rendered result of the render()
call. Otherwise,
runtime exceptions are propagated outwards.
imports – String list of Python statements, typically individual “import” lines, which will be placed into the module level preamble of all generated Python modules. See the example in The default_filters Argument.
future_imports – String list of names to import from __future__.
These will be concatenated into a comma-separated string and inserted
into the beginning of the template, e.g. futures_imports=['FOO',
'BAR']
results in from __future__ import FOO, BAR
. If you’re
interested in using features like the new division operator, you must
use future_imports to convey that to the renderer, as otherwise the
import will not appear as the first executed statement in the generated
code and will therefore not have the desired effect.
include_error_handler –
An error handler that runs when this template
is included within another one via the <%include>
tag, and raises an
error. Compare to the Template.error_handler
option.
New in version 1.0.6.
See also
Template.error_handler
- top-level error handler function
input_encoding – Encoding of the template’s source code. Can be used in lieu of the coding comment. See Using Unicode and Encoding as well as The Unicode Chapter for details on source encoding.
lookup – a TemplateLookup
instance that will be used
for all file lookups via the <%namespace>
,
<%include>
, and <%inherit>
tags. See
Using TemplateLookup.
module_directory – Filesystem location where generated Python module files will be placed.
module_filename – Overrides the filename of the generated Python module file. For advanced usage only.
module_writer –
A callable which overrides how the Python module is written entirely. The callable is passed the encoded source content of the module and the destination path to be written to. The default behavior of module writing uses a tempfile in conjunction with a file move in order to make the operation atomic. So a user-defined module writing function that mimics the default behavior would be:
import tempfile
import os
import shutil
def module_writer(source, outputpath):
(dest, name) = \\
tempfile.mkstemp(
dir=os.path.dirname(outputpath)
)
os.write(dest, source)
os.close(dest)
shutil.move(name, outputpath)
from mako.template import Template
mytemplate = Template(
filename="index.html",
module_directory="/path/to/modules",
module_writer=module_writer
)
The function is provided for unusual configurations where certain platform-specific permissions or other special steps are needed.
output_encoding – The encoding to use when render()
is called.
See Using Unicode and Encoding as well as The Unicode Chapter.
preprocessor – Python callable which will be passed the full template source before it is parsed. The return result of the callable will be used as the template source code.
lexer_cls –
A Lexer
class used to parse
the template. The Lexer
class is used by
default.
New in version 0.7.4.
strict_undefined –
Replaces the automatic usage of
UNDEFINED
for any undeclared variables not located in
the Context
with an immediate raise of
NameError
. The advantage is immediate reporting of
missing variables which include the name.
New in version 0.3.6.
uri – string URI or other identifier for this template.
If not provided, the uri
is generated from the filesystem
path, or from the in-memory identity of a non-file-based
template. The primary usage of the uri
is to provide a key
within TemplateLookup
, as well as to generate the
file path of the generated Python module file, if
module_directory
is specified.
mako.template.Template.
code¶Return the module source code for this Template
.
mako.template.Template.
get_def(name)¶Return a def of this template as a DefTemplate
.
mako.template.Template.
list_defs()¶return a list of defs in the template.
New in version 1.0.4.
mako.template.Template.
render(*args, **data)¶Render the output of this template as a string.
If the template specifies an output encoding, the string
will be encoded accordingly, else the output is raw (raw
output uses cStringIO and can’t handle multibyte
characters). A Context
object is created corresponding
to the given data. Arguments that are explicitly declared
by this template’s internal rendering method are also
pulled from the given *args
, **data
members.
mako.template.Template.
render_context(context, *args, **kwargs)¶Render this Template
with the given context.
The data is written to the context’s buffer.
mako.template.Template.
render_unicode(*args, **data)¶Render the output of this template as a unicode object.
mako.template.Template.
source¶Return the template source code for this Template
.
Bases: Template
A Template
which represents a callable def in a parent
template.
Members
Class signature
mako.template.DefTemplate.
get_def(name)¶Return a def of this template as a DefTemplate
.
Bases: object
Represent a collection of Template
objects,
identifiable via URI.
A TemplateCollection
is linked to the usage of
all template tags that address other templates, such
as <%include>
, <%namespace>
, and <%inherit>
.
The file
attribute of each of those tags refers
to a string URI that is passed to that Template
object’s TemplateCollection
for resolution.
TemplateCollection
is an abstract class,
with the usual default implementation being TemplateLookup
.
mako.lookup.TemplateCollection.
adjust_uri(uri, filename)¶Adjust the given uri
based on the calling filename
.
When this method is called from the runtime, the
filename
parameter is taken directly to the filename
attribute of the calling template. Therefore a custom
TemplateCollection
subclass can place any string
identifier desired in the filename
parameter of the
Template
objects it constructs and have them come back
here.
mako.lookup.TemplateCollection.
filename_to_uri(uri, filename)¶Convert the given filename
to a URI relative to
this TemplateCollection
.
mako.lookup.TemplateCollection.
get_template(uri, relativeto=None)¶Return a Template
object corresponding to the given
uri
.
The default implementation raises
NotImplementedError
. Implementations should
raise TemplateLookupException
if the given uri
cannot be resolved.
uri – String URI of the template to be resolved.
relativeto – if present, the given uri
is assumed to
be relative to this URI.
mako.lookup.TemplateCollection.
has_template(uri)¶Return True
if this TemplateLookup
is
capable of returning a Template
object for the
given uri
.
uri – String URI of the template to be resolved.
Bases: TemplateCollection
Represent a collection of templates that locates template source files from the local filesystem.
The primary argument is the directories
argument, the list of
directories to search:
lookup = TemplateLookup(["/path/to/templates"])
some_template = lookup.get_template("/index.html")
The TemplateLookup
can also be given Template
objects
programatically using put_string()
or put_template()
:
lookup = TemplateLookup()
lookup.put_string("base.html", '''
<html><body>${self.next()}</body></html>
''')
lookup.put_string("hello.html", '''
<%include file='base.html'/>
Hello, world !
''')
directories – A list of directory names which will be searched for a particular template URI. The URI is appended to each directory and the filesystem checked.
collection_size – Approximate size of the collection used
to store templates. If left at its default of -1
, the size
is unbounded, and a plain Python dictionary is used to
relate URI strings to Template
instances.
Otherwise, a least-recently-used cache object is used which
will maintain the size of the collection approximately to
the number given.
filesystem_checks – When at its default value of True
,
each call to TemplateLookup.get_template()
will
compare the filesystem last modified time to the time in
which an existing Template
object was created.
This allows the TemplateLookup
to regenerate a
new Template
whenever the original source has
been updated. Set this to False
for a very minor
performance increase.
modulename_callable – A callable which, when present,
is passed the path of the source file as well as the
requested URI, and then returns the full path of the
generated Python module file. This is used to inject
alternate schemes for Python module location. If left at
its default of None
, the built in system of generation
based on module_directory
plus uri
is used.
All other keyword parameters available for
Template
are mirrored here. When new
Template
objects are created, the keywords
established with this TemplateLookup
are passed on
to each new Template
.
Class signature
class mako.lookup.TemplateLookup
(mako.lookup.TemplateCollection
)
mako.lookup.TemplateLookup.
adjust_uri(uri, relativeto)¶Adjust the given uri
based on the given relative URI.
mako.lookup.TemplateLookup.
filename_to_uri(filename)¶Convert the given filename
to a URI relative to
this TemplateCollection
.
mako.lookup.TemplateLookup.
get_template(uri)¶Return a Template
object corresponding to the given
uri
.
Note
The relativeto
argument is not supported here at
the moment.
mako.lookup.TemplateLookup.
put_string(uri, text)¶Place a new Template
object into this
TemplateLookup
, based on the given string of
text
.
mako.lookup.TemplateLookup.
put_template(uri, template)¶Place a new Template
object into this
TemplateLookup
, based on the given
Template
object.
Bases: object
Pull the current exception from the sys
traceback and extracts
Mako-specific template information.
Members
error, message, source, lineno, records, reverse_records, reverse_traceback
See the usage examples in Handling Exceptions.
mako.exceptions.RichTraceback.
error¶the exception instance.
mako.exceptions.RichTraceback.
message¶the exception error message as unicode.
mako.exceptions.RichTraceback.
source¶source code of the file where the error occurred. If the error occurred within a compiled template, this is the template source.
mako.exceptions.RichTraceback.
lineno¶line number where the error occurred. If the error occurred within a compiled template, the line number is adjusted to that of the template source.
mako.exceptions.RichTraceback.
records¶a list of 8-tuples containing the original
python traceback elements, plus the
filename, line number, source line, and full template source
for the traceline mapped back to its originating source
template, if any for that traceline (else the fields are None
).
mako.exceptions.RichTraceback.
reverse_records¶the list of records in reverse traceback – a list of 4-tuples, in the same format as a regular python traceback, with template-corresponding traceback records replacing the originals.
mako.exceptions.RichTraceback.
reverse_traceback¶the traceback list in reverse.
Provides a template that renders a stack trace in an HTML format, providing an excerpt of code as well as substituting source template filenames, line numbers and code for that of the originating source template, as applicable.
The template’s default encoding_errors
value is
'htmlentityreplace'
. The template has two options. With the
full
option disabled, only a section of an HTML document is
returned. With the css
option disabled, the default stylesheet
won’t be included.
Provides a template that renders a stack trace in a similar format to the Python interpreter, substituting source template filenames, line numbers and code for that of the originating source template, as applicable.