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:

    #. 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.
