Basic Usage {@name=usage}
==========================

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](rel:syntax).

The most basic way to create a template and render it is through the `Template` class:

    {python}
    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 it's 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 `render()` method:

    {python}
    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 `render_context` method:

    {python}
    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()

### Using File-Based Templates {@name=file}

A `Template` can also load its template source code from a file, using the `filename` keyword argument:

    {python}
    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:

    {python}
    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.

### Using TemplateLookup {@name=lookup}

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.

    {python}
    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 `get_template` method, which accepts the URI of the desired template:

    {python}
    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 `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`.

#### Setting the Collection Size {@name=size}

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:

    {python}
    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.

#### Setting Filesystem Checks {@name=checks}

Another important flag on `TemplateLookup` is `filesystem_checks`.  This defaults to `True`, and says that each time a template is returned by the `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, seting `filesystem_checks` to `False` can afford a small to moderate performance increase (depending on the type of filesystem used).

### Using Unicode and Encoding

Both `Template` and `TemplateLookup` accept `output_encoding` and `encoding_errors` parameters which can be used to encode the output in any Python supported codec:

    {python}
    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()
    
Additionally, the `render_unicode()` method exists which will return the template output as a Python `unicode` object:

    {python}
    print mytemplate.render_unicode()
    
The above method disgards the output encoding keyword argument; you can encode yourself by saying:

    {python}
    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 [unicode](rel:unicode).

### Handling Exceptions

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:

    {python}
    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:

    {python}
    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`.

    {python}
    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:

    {python}
    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 `RichTraceback` is available within the module-level documentation for `mako.exceptions`.


### Common Framework Integrations

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.

#### Turbogears/Pylons Plugin

The standard plugin methodology used by [Turbogears](http://www.turbogears.org) as well as [Pylons](http://www.pylonshq.com) is included in the module `mako.ext.turbogears`, using the `TGPlugin` class.  This is also a setuptools entrypoint under the heading `python.templating.engines` with the name `mako`.

#### WSGI

A sample WSGI application is included in the distrubution 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.

#### Pygments

A [Pygments](http://pygments.pocoo.org)-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).

#### Babel (Internationalization)

Mako provides support for extracting gettext messages from templates via a [Babel](http://babel.edgewall.org/) extractor entry point under `mako.ext.babelplugin`.

Gettext messages are extracted from all Python code sections, even the more obscure ones such as [control structures](rel:syntax_control), [def tag function declarations](rel:defs), [call tag exprs](rel:defs_defswithcontent) and even [page tag args](rel:syntax_tags_page).

[Translator comments](http://babel.edgewall.org/wiki/Documentation/messages.html#comments-tags-and-translator-comments-explanation) may also be extracted from Mako templates when a comment tag is specified to [Babel](http://babel.edgewall.org/) (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](http://babel.edgewall.org/wiki/Documentation/messages.html#extraction-method-mapping-and-configuration) (typically located at myproj/babel.cfg):

    {ini}
    # 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](http://babel.edgewall.org/)'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](http://babel.edgewall.org/) can be invoked from setup.py and its command line options specified in the accompanying setup.cfg via [Babel Distutils/Setuptools Integration](http://babel.edgewall.org/wiki/Documentation/setup.html).

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](http://babel.edgewall.org/wiki/Documentation/index.html) for more information.
