Namespaces are used to organize groups of defs into categories, and also to “import” defs from other files.
If the file components.html
defines these two defs:
## 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 defs into a namespace called comp
:
## index.html
<%namespace name="comp" file="components.html"/>
Here's comp1: ${comp.comp1()}
Here's comp2: ${comp.comp2(x=5)}
The comp
variable above is an instance of
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 “.
” operator. 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.
The file
argument allows expressions – if looking for
context variables, the context
must be named explicitly:
<%namespace name="dyn" file="${context['namespace_name']}"/>
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.
Namespaces can also import regular Python functions from
modules. These callables need to take at least one argument,
context
, an instance of 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")
The <%namespace>
tag supports the definition of <%def>
s
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()}
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 Context.kwargs
accessor, for cases when you’d like to pass along the top level context
arguments 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.
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.
self
¶The self
namespace, in the case of a template that does not
use inheritance, is synonymous 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.
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.
The <%namespace>
tag at runtime produces an instance of
Namespace
. Programmatic access of Namespace
can be used
to build various kinds of scaffolding in templates and between templates.
A common request is the ability for a particular template to declare
“static includes” - meaning, the usage of a particular set of defs requires
that certain Javascript/CSS files are present. Using Namespace
as the
object that holds together the various templates present, we can build a variety
of such schemes. In particular, the Context
has a namespaces
attribute, which is a dictionary of all Namespace
objects declared.
Iterating the values of this dictionary will provide a Namespace
object for each time the <%namespace>
tag was used, anywhere within the
inheritance chain.
Namespace.attr
¶The Namespace.attr
attribute allows us to locate any variables declared
in the <%! %>
of a template.
## base.mako
## base-most template, renders layout etc.
<html>
<head>
## traverse through all namespaces present,
## look for an attribute named 'includes'
% for ns in context.namespaces.values():
% for incl in getattr(ns.attr, 'includes', []):
${incl}
% endfor
% endfor
</head>
<body>
${next.body()}
</body
</html>
## library.mako
## library functions.
<%!
includes = [
'<link rel="stylesheet" type="text/css" href="mystyle.css"/>',
'<script type="text/javascript" src="functions.js"></script>'
]
%>
<%def name="mytag()">
<form>
${caller.body()}
</form>
</%def>
## index.mako
## calling template.
<%inherit file="base.mako"/>
<%namespace name="foo" file="library.mako"/>
<%foo:mytag>
a form
</%foo:mytag>
Above, the file library.mako
declares an attribute includes
inside its global <%! %>
section.
index.mako
includes this template using the <%namespace>
tag. The base template base.mako
, which is the inherited parent of index.mako
and is responsible for layout, then locates this attribute and iterates through its contents to produce the includes that are specific to library.mako
.
In this version, we put the includes into a <%def>
that
follows a naming convention.
## base.mako
## base-most template, renders layout etc.
<html>
<head>
## traverse through all namespaces present,
## look for a %def named 'includes'
% for ns in context.namespaces.values():
% if hasattr(ns, 'includes'):
${ns.includes()}
% endif
% endfor
</head>
<body>
${next.body()}
</body
</html>
## library.mako
## library functions.
<%def name="includes()">
<link rel="stylesheet" type="text/css" href="mystyle.css"/>
<script type="text/javascript" src="functions.js"></script>
</%def>
<%def name="mytag()">
<form>
${caller.body()}
</form>
</%def>
## index.mako
## calling template.
<%inherit file="base.mako"/>
<%namespace name="foo" file="library.mako"/>
<%foo:mytag>
a form
</%foo:mytag>
In this version, library.mako
declares a <%def>
named includes
. The example works
identically to the previous one, except that base.mako
looks for defs named include
on each namespace it examines.
Object Name | Description |
---|---|
capture(context, callable_, *args, **kwargs) |
Execute the given template def, capturing the output into a buffer. |
Bases: |
|
Bases: |
|
supports_caller(func) |
Apply a caller_stack compatibility decorator to a plain Python function. |
Bases: |
Bases: object
Provides access to collections of rendering methods, which can be local, from other templates, or from imported modules.
To access a particular rendering method referenced by a
Namespace
, use plain attribute access:
${some_namespace.foo(x, y, z)}
Members
attr, cache, context, filename, get_cached(), get_namespace(), get_template(), include_file(), module, template, uri
Namespace
also contains several built-in attributes
described here.
mako.runtime.Namespace.
attr¶Access module level attributes by name.
This accessor allows templates to supply “scalar” attributes which are particularly handy in inheritance relationships.
mako.runtime.Namespace.
cache¶Return the Cache
object referenced
by this Namespace
object’s
Template
.
mako.runtime.Namespace.
context = None¶The Context
object for this Namespace
.
Namespaces are often created with copies of contexts that
contain slightly different data, particularly in inheritance
scenarios. Using the Context
off of a Namespace
one
can traverse an entire chain of templates that inherit from
one-another.
mako.runtime.Namespace.
filename = None¶The path of the filesystem file used for this
Namespace
’s module or template.
If this is a pure module-based
Namespace
, this evaluates to module.__file__
. If a
template-based namespace, it evaluates to the original
template file location.
mako.runtime.Namespace.
get_cached(key, **kwargs)¶Return a value from the Cache
referenced by this
Namespace
object’s Template
.
The advantage to this method versus direct access to the
Cache
is that the configuration parameters
declared in <%page>
take effect here, thereby calling
up the same configured backend as that configured
by <%page>
.
mako.runtime.Namespace.
get_namespace(uri)¶Return a Namespace
corresponding to the given uri
.
If the given uri
is a relative URI (i.e. it does not
contain a leading slash /
), the uri
is adjusted to
be relative to the uri
of the namespace itself. This
method is therefore mostly useful off of the built-in
local
namespace, described in local.
In
most cases, a template wouldn’t need this function, and
should instead use the <%namespace>
tag to load
namespaces. However, since all <%namespace>
tags are
evaluated before the body of a template ever runs,
this method can be used to locate namespaces using
expressions that were generated within the body code of
the template, or to conditionally use a particular
namespace.
mako.runtime.Namespace.
get_template(uri)¶Return a Template
from the given uri
.
The uri
resolution is relative to the uri
of this
Namespace
object’s Template
.
mako.runtime.Namespace.
include_file(uri, **kwargs)¶Include a file at the given uri
.
mako.runtime.Namespace.
module = None¶The Python module referenced by this Namespace
.
If the namespace references a Template
, then
this module is the equivalent of template.module
,
i.e. the generated module for the template.
mako.runtime.Namespace.
template = None¶mako.runtime.Namespace.
uri = None¶The URI for this Namespace
’s template.
I.e. whatever was sent to TemplateLookup.get_template()
.
This is the equivalent of Template.uri
.
Bases: Namespace
A Namespace
specific to a Template
instance.
Class signature
class mako.runtime.TemplateNamespace
(mako.runtime.Namespace
)
mako.runtime.TemplateNamespace.
filename¶The path of the filesystem file used for this
Namespace
’s module or template.
If this is a pure module-based
Namespace
, this evaluates to module.__file__
. If a
template-based namespace, it evaluates to the original
template file location.
mako.runtime.TemplateNamespace.
module¶The Python module referenced by this Namespace
.
If the namespace references a Template
, then
this module is the equivalent of template.module
,
i.e. the generated module for the template.
mako.runtime.TemplateNamespace.
uri¶The URI for this Namespace
’s template.
I.e. whatever was sent to TemplateLookup.get_template()
.
This is the equivalent of Template.uri
.
Bases: Namespace
A Namespace
specific to a Python module instance.
Members
Class signature
mako.runtime.ModuleNamespace.
filename¶The path of the filesystem file used for this
Namespace
’s module or template.
If this is a pure module-based
Namespace
, this evaluates to module.__file__
. If a
template-based namespace, it evaluates to the original
template file location.
Apply a caller_stack compatibility decorator to a plain Python function.
See the example in Namespaces from Regular Python Modules.
Execute the given template def, capturing the output into a buffer.
See the example in Namespaces from Regular Python Modules.