# -*- coding: utf-8 -*- <%inherit file="content_layout.html"/> <%page args="toc, extension, paged"/> <%namespace name="formatting" file="formatting.html"/> <%namespace name="nav" file="nav.html"/> <%def name="title()">Mako Documentation - The Mako Runtime Environment%def> <%! filename = 'runtime' %> ## This file is generated. Edit the .txt files instead of this one. <%call expr="formatting.section(path='runtime',paged=paged,extension=extension,toc=toc)">
This section describes a little bit about the objects and built-in functions that are available in templates.
<%call expr="formatting.section(path='runtime_context',paged=paged,extension=extension,toc=toc)">The <%text filter='h'>Context%text>
is the central object that is created when a template is first executed, and is responsible for handling all communication with the outside world. This includes two major components, one of which is the output buffer, which is a file-like object such as Python's <%text filter='h'>StringIO%text>
or similar, and the other a dictionary of variables that can be freely referenced within a template; this dictionary is a combination of the arguments sent to the <%text filter='h'>template.render()%text>
function and some built-in variables provided by Mako's runtime environment.
The buffer is stored within the <%text filter='h'>Context%text>
, and writing to it is achieved by calling <%text filter='h'>context.write()%text>
. You usually don't need to care about this as all text within a template, as well as all expressions provided by <%text filter='h'>${}%text>
, automatically send everything to this method. The cases you might want to be aware of its existence are if you are dealing with various filtering/buffering scenarios, which are described in <%call expr="nav.toclink(path='filtering',paged=paged,extension=extension,toc=toc)">%call>, or if you want to programmatically send content to the output stream, such as within a <%text filter='h'><% %>%text>
block.
The actual buffer may or may not be the original buffer sent to the <%text filter='h'>Context%text>
object, as various filtering/caching scenarios may "push" a new buffer onto the context's underlying buffer stack. For this reason, just stick with <%text filter='h'>context.write()%text>
and content will always go to the topmost buffer.
When your template is compiled into a Python module, the body content is enclosed within a Python function called <%text filter='h'>render_body%text>
. Other top-level defs defined in the template are defined within their own function bodies which are named after the def's name with the prefix <%text filter='h'>render_%text>
(i.e. <%text filter='h'>render_mydef%text>
). One of the first things that happens within these functions is that all variable names that are referenced within the function which are not defined in some other way (i.e. such as via assignment, module level imports, etc.) are pulled from the <%text filter='h'>Context%text>
object's dictionary of variables. This is how you're able to freely reference variable names in a template which automatically correspond to what was passed into the current <%text filter='h'>Context%text>
.
What happens if I reference a variable name that is not in the current context? - the value you get back is a special value called <%text filter='h'>UNDEFINED%text>
. This is just a simple global variable with the class <%text filter='h'>mako.runtime.Undefined%text>
. The <%text filter='h'>UNDEFINED%text>
object throws an error when you call <%text filter='h'>str()%text>
on it, which is what happens if you try to use it in an expression.
Why not just return None? Using <%text filter='h'>UNDEFINED%text>
is more explicit and allows differentiation between a value of <%text filter='h'>None%text>
that was explicitly passed to the <%text filter='h'>Context%text>
and a value that wasn't present at all.
Why raise an exception when you call str() on it ? Why not just return a blank string? - Mako tries to stick to the Python philosophy of "explicit is better than implicit". In this case, its decided that the template author should be made to specifically handle a missing value rather than experiencing what may be a silent failure. Since <%text filter='h'>UNDEFINED%text>
is a singleton object just like Python's <%text filter='h'>True%text>
or <%text filter='h'>False%text>
, you can use the <%text filter='h'>is%text>
operator to check for it:
Another facet of the <%text filter='h'>Context%text>
is that its dictionary of variables is immutable. Whatever is set when <%text filter='h'>template.render()%text>
is called is what stays. Of course, since its Python, you can hack around this and change values in the context's internal dictionary, but this will probably will not work as well as you'd think. The reason for this is that Mako in many cases creates copies of the <%text filter='h'>Context%text>
object, which get sent to various elements of the template and inheriting templates used in an execution. So changing the value in your local <%text filter='h'>Context%text>
will not necessarily make that value available in other parts of the template's execution. Examples of where Mako creates copies of the <%text filter='h'>Context%text>
include within top-level def calls from the main body of the template (the context is used to propagate locally assigned variables into the scope of defs; since in the template's body they appear as inlined functions, Mako tries to make them act that way), and within an inheritance chain (each template in an inheritance chain has a different notion of <%text filter='h'>parent%text>
and <%text filter='h'>next%text>
, which are all stored in unique <%text filter='h'>Context%text>
instances).
<%text filter='h'>Context%text>
when the template first runs, and everyone can just get/set variables from that. Lets say its called <%text filter='h'>attributes%text>
.
Running the template looks like:
<%call expr="formatting.code(syntaxtype='python')"><%text> output = template.render(attributes={}) %text>%call>Within a template, just reference the dictionary:
<%call expr="formatting.code()"><%text><% attributes['foo'] = 'bar' %> 'foo' attribute is: ${attributes['foo']} %text>%call>Significant members off of <%text filter='h'>Context%text>
include:
<%text filter='h'>context[key]%text>
/ <%text filter='h'>context.get(key, default=None)%text>
- dictionary-like accessors for the context. Normally, any variable you use in your template is automatically pulled from the context if it isnt defined somewhere already. Use the dictionary accessor and/or <%text filter='h'>get%text>
method when you want a variable that is already defined somewhere else, such as in the local arguments sent to a %def call. If a key is not present, like a dictionary it raises <%text filter='h'>KeyError%text>
.
<%text filter='h'>keys()%text>
- all the names defined within this context.
<%text filter='h'>kwargs%text>
- this returns a copy of the context's dictionary of variables. This is useful when you want to propagate the variables in the current context to a function as keyword arguments, i.e.:
<%text filter='h'>write(text)%text>
- write some text to the current output stream.
<%text filter='h'>lookup%text>
- returns the <%text filter='h'>TemplateLookup%text>
instance that is used for all file-lookups within the current execution (even though individual <%text filter='h'>Template%text>
instances can conceivably have different instances of a <%text filter='h'>TemplateLookup%text>
, only the <%text filter='h'>TemplateLookup%text>
of the originally-called <%text filter='h'>Template%text>
gets used in a particular execution).
A one-stop shop for all the names Mako defines. Most of these names are instances of <%text filter='h'>Namespace%text>
, which are described in the next section, <%call expr="nav.toclink(path='namespaces',paged=paged,extension=extension,toc=toc)">%call>. Also, most of these names other than <%text filter='h'>context%text>
and <%text filter='h'>UNDEFINED%text>
are also present within the <%text filter='h'>Context%text>
itself.
<%text filter='h'>local%text>
- the namespace of the current template, described in <%call expr="nav.toclink(path='namespaces_builtin',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>self%text>
- the namespace of the topmost template in an inheritance chain (if any, otherwise the same as <%text filter='h'>local%text>
), mostly described in <%call expr="nav.toclink(path='inheritance',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>parent%text>
- the namespace of the parent template in an inheritance chain (otherwise undefined); see <%call expr="nav.toclink(path='inheritance',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>next%text>
- the namespace of the next template in an inheritance chain (otherwise undefined); see <%call expr="nav.toclink(path='inheritance',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>caller%text>
- a "mini" namespace created when using the <%text filter='h'><%call>%text>
tag to define a "def call with content"; described in <%call expr="nav.toclink(path='defs_defswithcontent',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>capture%text>
- a function that calls a given def and captures its resulting content into a string, which is returned. Usage is described in <%call expr="nav.toclink(path='filtering_buffering',paged=paged,extension=extension,toc=toc)">%call>
<%text filter='h'>UNDEFINED%text>
- a global singleton that is applied to all otherwise uninitialized template variables that were not located within the <%text filter='h'>Context%text>
when rendering began. Is an instance of <%text filter='h'>mako.runtime.Undefined%text>
, and raises an exception when its <%text filter='h'>__str__()%text>
method is called.
<%text filter='h'>pageargs%text>
- this is a dictionary which is present in a template which does not define any kwargs section in its <%text filter='h'><%page>%text>
tag. All keyword arguments sent to the <%text filter='h'>body()%text>
function of a template (when used via namespaces) go here by default unless otherwise defined as a page argument. If this makes no sense, it shouldn't; read the section <%call expr="nav.toclink(path='namespaces_body',paged=paged,extension=extension,toc=toc)">%call>.