Multiple Pages | One Page

Mako Documentation

Version: 0.3.4 Last Updated: 06/22/10 17:39:23

Table of Contents


Namespaces

Namespaces

Namespaces are used to organize groups of components into categories, and also to "import" components from other files.

If the file components.html defines these two components:

## components.html
<%def name="comp1()">
    this is comp1
</%def>

<%def name="comp2(x)">
    this is comp2, x is ${x}
</%def>

You can make another file, for example index.html, that pulls those two components into a namespace called comp:

## index.html
<%namespace name="comp" file="components.html"/>

Heres comp1:  ${comp.comp1()}
Heres comp2:  ${comp.comp2(x=5)}

The comp variable above is an instance of mako.runtime.Namespace, a proxy object which delivers method calls to the underlying template callable using the current context.

<%namespace> also provides an import attribute which can be used to pull the names into the local namespace, removing the need to call it via the ".". When import is used, the name attribute is optional.

<%namespace file="components.html" import="comp1, comp2"/>

Heres comp1:  ${comp1()}
Heres comp2:  ${comp2(x=5)}

import also supports the "*" operator:

<%namespace file="components.html" import="*"/>

Heres comp1:  ${comp1()}
Heres comp2:  ${comp2(x=5)}

The names imported by the import attribute take precedence over any names that exist within the current context.

Note - in current versions of Mako, usage of "import='*'" is known to decrease performance of the template. This will be fixed in a future release.

Ways to Call Namespaces

There are essentially four ways to call a function from a namespace.

The "expression" format, as described previously. Namespaces are just Python objects with functions on them, and can be used in expressions like any other function:

${mynamespace.somefunction('some arg1', 'some arg2', arg3='some arg3', arg4='some arg4')}

Synonymous with the "expression" format is the "custom tag" format, when a "closed" tag is used. This format, introduced in Mako 0.2.3, allows the usage of a "custom" Mako tag, with the function arguments passed in using named attributes:

<%mynamespace:somefunction arg1="some arg1" arg2="some arg2" arg3="some arg3" arg4="some arg4"/>

When using tags, the values of the arguments are taken as literal strings by default. To embed Python expressions as arguments, use the embedded expression format:

<%mynamespace:somefunction arg1="${someobject.format()}" arg2="${somedef(5, 12)}"/>

The "custom tag" format is intended mainly for namespace functions which recognize body content, which in Mako is known as a "def with embedded content":

<%mynamespace:somefunction arg1="some argument" args="x, y">
    Some record: ${x}, ${y}
</%mynamespace:somefunction>

The "classic" way to call defs with embedded content is the <%call> tag:

<%call expr="mynamespace.somefunction(arg1='some argument')" args="x, y">
    Some record: ${x}, ${y}
</%call>

For information on how to construct defs that embed content from the caller, see Calling a def with embedded content and/or other defs.

back to section top

Namespaces from Regular Python Modules

Namespaces can also import regular Python functions from modules. These callables need to take at least one argument, context:

A module file some/module.py might contain the callable:

def my_tag(context):
    context.write("hello world")
    return ''

A template can use this module via:

<%namespace name="hw" module="some.module"/>

${hw.my_tag()}

Note that the context argument is not needed in the call; the namespace tag creates a locally-scoped callable which takes care of it. The return '' is so that the def does not dump a None into the output stream - the return value of any def is rendered after the def completes, in addition to whatever was passed to context.write() within its body.

If your def is to be called in an "embedded content" context, that is as described in Calling a def with embedded content and/or other defs, you should use the @supports_caller decorator, which will ensure that Mako will ensure the correct "caller" variable is available when your def is called, supporting embedded content:

from mako.runtime import supports_caller

@supports_caller
def my_tag(context):
    context.write("<div>")
    context['caller'].body()
    context.write("</div>")
    return ''

Capturing of output is available as well, using the outside-of-templates version of the capture() function, which accepts the "context" as its first argument:

from mako.runtime import supports_caller, capture

@supports_caller
def my_tag(context):
    return "<div>%s</div>" % \
            capture(context, context['caller'].body, x="foo", y="bar")
back to section top

Declaring defs in namespaces.

The <%namespace> tag supports the definition of <%defs> directly inside the tag. These defs become part of the namespace like any other function, and will override the definitions pulled in from a remote template or module:

## define a namespace
<%namespace name="stuff">
    <%def name="comp1()">
        comp1
    </%def>
</%namespace>

## then call it
${stuff.comp1()}
back to section top

The "body()" method

Every namespace that is generated from a template contains a method called body(). This method corresponds to the main body of the template, and plays its most important roles when using inheritance relationships as well as def-calls-with-content.

Since the body() method is available from a namespace just like all the other defs defined in a template, what happens if you send arguments to it ? By default, the body() method accepts no positional arguments, and for usefulness in inheritance scenarios will by default dump all keyword arguments into a dictionary called pageargs. But if you actually want to get at the keyword arguments, Mako recommends you define your own argument signature explicitly. You do this via using the <%page> tag:

<%page args="x, y, someval=8, scope='foo', **kwargs"/>

A template which defines the above signature requires that the variables x and y are defined, defines default values for someval and scope, and sets up **kwargs to receive all other keyword arguments. If **kwargs or similar is not present, the argument **pageargs gets tacked on by Mako. When the template is called as a top-level template (i.e. via template.render()) or via the <%include> tag, the values for these arguments will be pulled from the Context. In all other cases, i.e. via calling the body() method, the arguments are taken as ordinary arguments from the method call. So above, the body might be called as:

${self.body(5, y=10, someval=15, delta=7)}

The Context object also supplies a kwargs accessor, for cases when youd like to pass along whatever is in the context to a body() callable:

${next.body(**context.kwargs)}

The usefulness of calls like the above become more apparent when one works with inheriting templates. For more information on this, as well as the meanings of the names self and next, see Inheritance.

back to section top

Namespace methods and properties

The Namespace class includes helpful accessors and methods:

back to section top

Built-in Namespaces

The namespace is so great that Mako gives your template one (or two) for free. The names of these namespaces are local and self. Other built-in namespaces include parent and next, which are optional and are described in Inheritance.

local

The local namespace is basically the namespace for the currently executing template. This means that all of the top level defs defined in your template, as well as your template's body() function, are also available off of the local namespace.

The local namespace is also where properties like uri, filename, and module and the get_namespace method can be particularly useful.

back to section top

self

The self namespace, in the case of a template that does not use inheritance, is synonomous with local. If inheritance is used, then self references the topmost template in the inheritance chain, where it is most useful for providing the ultimate form of various "method" calls which may have been overridden at various points in an inheritance chain. See Inheritance.

back to section top

Inheritable Namespaces

The <%namespace> tag includes an optional attribute inheritable="True", which will cause the namespace to be attached to the self namespace. Since self is globally available throughout an inheritance chain (described in the next section), all the templates in an inheritance chain can get at the namespace imported in a super-template via self.

## base.html
<%namespace name="foo" file="foo.html" inheritable="True"/>

${next.body()}

## somefile.html
<%inherit file="base.html"/>

${self.foo.bar()}

This allows a super-template to load a whole bunch of namespaces that its inheriting templates can get to, without them having to explicitly load those namespaces themselves.

The import="*" part of the <%namespace> tag doesn't yet interact with the inheritable flag, so currently you have to use the explicit namespace name off of self, followed by the desired function name. But more on this in a future release.

back to section top
Previous: The Mako Runtime Environment | Next: Inheritance

Table of Contents