summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2010-11-12 17:27:11 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2010-11-12 17:27:11 -0500
commita9da8487c7da377c9378bd5c997cc96ce7079efa (patch)
tree8cba4a1248ff10feff9e26caf40ca9a10f4ed5c0
parent4ce916525fd94116e696f4d8cde19333e9ed946c (diff)
downloadmako-a9da8487c7da377c9378bd5c997cc96ce7079efa.tar.gz
looks good
-rw-r--r--doc/build/caching.rst120
-rw-r--r--doc/build/filtering.rst339
-rw-r--r--doc/build/inheritance.rst320
-rw-r--r--doc/build/namespaces.rst382
-rw-r--r--doc/build/runtime.rst237
-rw-r--r--doc/build/syntax.rst5
-rw-r--r--doc/build/unicode.rst330
-rw-r--r--doc/build/usage.rst10
-rw-r--r--mako/lookup.py4
-rw-r--r--mako/runtime.py83
10 files changed, 1810 insertions, 20 deletions
diff --git a/doc/build/caching.rst b/doc/build/caching.rst
index 8b13789..3ad35ff 100644
--- a/doc/build/caching.rst
+++ b/doc/build/caching.rst
@@ -1 +1,121 @@
+.. _caching_toplevel:
+========
+Caching
+========
+
+Any template or component can be cached using the ``cache``
+argument to the ``<%page>`` or ``<%def>`` directives:
+
+.. sourcecode:: mako
+
+ <%page cached="True"/>
+
+ template text
+
+The above template, after being executed the first time, will
+store its content within a cache that by default is scoped
+within memory. Subsequent calls to the template's :meth:`~.Template.render`
+method will return content directly from the cache. When the
+:class:`.Template` object itself falls out of scope, its corresponding
+cache is garbage collected along with the template.
+
+Caching requires that the ``beaker`` package be installed on the
+system.
+
+The caching flag and all its options can be used with the
+``<%def>`` tag.
+
+.. sourcecode:: mako
+
+ <%def name="mycomp" cached="True" cache_timeout="30" cache_type="memory">
+ other text
+ </%def>
+
+Cache arguments
+================
+
+The various cache arguments are cascaded from their default
+values, to the arguments specified programmatically to the
+:class:`.Template` or its originating :class:`.TemplateLookup`, then to those
+defined in the ``<%page>`` tag of an individual template, and
+finally to an individual ``<%def>`` tag within the template. This
+means you can define, for example, a cache type of ``dbm`` on your
+:class:`.TemplateLookup`, a cache timeout of 60 seconds in a particular
+template's ``<%page>`` tag, and within one of that template's
+``<%def>`` tags ``cache=True``, and that one particular def will
+then cache its data using a ``dbm`` cache and a data timeout of 60
+seconds.
+
+The options available are:
+
+* ``cached="False|True"`` - turn caching on
+* ``cache_timeout`` - number of seconds in which to invalidate the
+ cached data. after this timeout, the content is re-generated
+ on the next call.
+* ``cache_type`` - type of caching. ``memory``, ``file``, ``dbm``, or
+ ``memcached``.
+* ``cache_url`` - (only used for ``memcached`` but required) a single
+ IP address or a semi-colon separated list of IP address of
+ memcache servers to use.
+* ``cache_dir`` - In the case of the ``file`` and ``dbm`` cache types,
+ this is the filesystem directory with which to store data
+ files. If this option is not present, the value of
+ ``module_directory`` is used (i.e. the directory where compiled
+ template modules are stored). If neither option is available
+ an exception is thrown.
+
+ In the case of the ``memcached`` type, this attribute is required
+ and it's used to store the lock files.
+* ``cache_key`` - the "key" used to uniquely identify this content
+ in the cache. the total namespace of keys within the cache is
+ local to the current template, and the default value of "key"
+ is the name of the def which is storing its data. It is an
+ evaluable tag, so you can put a Python expression to calculate
+ the value of the key on the fly. For example, heres a page
+ that caches any page which inherits from it, based on the
+ filename of the calling template:
+
+.. sourcecode:: mako
+
+ <%page cached="True" cache_key="${self.filename}"/>
+
+ ${next.body()}
+
+ ## rest of template
+
+Accessing the Cache
+===================
+
+The :class:`.Template`, as well as any template-derived namespace, has
+an accessor called ``cache`` which returns the ``Cache`` object
+for that template. This object is a facade on top of the Beaker
+internal cache object, and provides some very rudimental
+capabilities, such as the ability to get and put arbitrary
+values:
+
+.. sourcecode:: mako
+
+ <%
+ local.cache.put("somekey", type="memory", "somevalue")
+ %>
+
+Above, the cache associated with the ``local`` namespace is
+accessed and a key is placed within a memory cache.
+
+More commonly the ``cache`` object is used to invalidate cached
+sections programmatically:
+
+.. sourcecode:: python
+
+ template = lookup.get_template('/sometemplate.html')
+
+ # invalidate the "body" of the template
+ template.cache.invalidate_body()
+
+ # invalidate an individual def
+ template.cache.invalidate_def('somedef')
+
+ # invalidate an arbitrary key
+ template.cache.invalidate('somekey')
+
diff --git a/doc/build/filtering.rst b/doc/build/filtering.rst
index 8b13789..0921176 100644
--- a/doc/build/filtering.rst
+++ b/doc/build/filtering.rst
@@ -1 +1,340 @@
+.. _filtering_toplevel:
+=======================
+Filtering and Buffering
+=======================
+
+Expression Filtering
+=====================
+
+As described in the chapter :ref:`syntax_toplevel`, the "``|``" operator can be
+applied to a "``${}``" expression to apply escape filters to the
+output:
+
+.. sourcecode:: mako
+
+ ${"this is some text" | u}
+
+The above expression applies URL escaping to the expression, and
+produces ``this+is+some+text``.
+
+The built-in escape flags are:
+
+* ``u`` : URL escaping, provided by
+ ``urllib.quote_plus(string.encode('utf-8'))``
+* ``h`` : HTML escaping, provided by
+ ``markupsafe.escape(string)`` (new as of 0.3.4 - prior
+ versions use ``cgi.escape(string, True)``)
+* ``x`` : XML escaping
+* ``trim`` : whitespace trimming, provided by ``string.strip()``
+* ``entity`` : produces HTML entity references for applicable
+ strings, derived from ``htmlentitydefs``
+* ``unicode`` (``str`` on Python 3): produces a Python unicode
+ string (this function is applied by default).
+* ``decode.<some encoding>`` : decode input into a Python
+ unicode with the specified encoding
+* ``n`` : disable all default filtering; only filters specified
+ in the local expression tag will be applied.
+
+To apply more than one filter, separate them by a comma:
+
+.. sourcecode:: mako
+
+ ${" <tag>some value</tag> " | h,trim}
+
+The above produces ``&lt;tag&gt;some value&lt;/tag&gt;``, with
+no leading or trailing whitespace. The HTML escaping function is
+applied first, the "trim" function second.
+
+Naturally, you can make your own filters too. A filter is just a
+Python function that accepts a single string argument, and
+returns the filtered result. The expressions after the ``|``
+operator draw upon the local namespace of the template in which
+they appear, meaning you can define escaping functions locally:
+
+.. sourcecode:: mako
+
+ <%!
+ def myescape(text):
+ return "<TAG>" + text + "</TAG>"
+ %>
+
+ Heres some tagged text: ${"text" | myescape}
+
+Or from any Python module:
+
+.. sourcecode:: mako
+
+ <%!
+ import myfilters
+ %>
+
+ Heres some tagged text: ${"text" | myfilters.tagfilter}
+
+A page can apply a default set of filters to all expression tags
+using the ``expression_filter`` argument to the ``%page`` tag:
+
+.. sourcecode:: mako
+
+ <%page expression_filter="h"/>
+
+ Escaped text: ${"<html>some html</html>"}
+
+Result:
+
+.. sourcecode:: html
+
+ Escaped text: &lt;html&gt;some html&lt;/html&gt;
+
+.. _filtering_default_filters:
+
+The default_filters Argument
+----------------------------
+
+In addition to the ``expression_filter`` argument, the
+``default_filters`` argument to both ``Template`` and
+``TemplateLookup`` can specify filtering for all expression tags
+at the programmatic level. This array-based argument, when given
+its default argument of ``None``, will be internally set to
+``["unicode"]`` (or ``["str"]`` on Python 3), except when
+``disable_unicode=True`` is set in which case it defaults to
+``["str"]``:
+
+.. sourcecode:: python
+
+ t = TemplateLookup(directories=['/tmp'], default_filters=['unicode'])
+
+To replace the usual ``unicode``/``str`` function with a
+specific encoding, the ``decode`` filter can be substituted:
+
+.. sourcecode:: python
+
+ t = TemplateLookup(directories=['/tmp'], default_filters=['decode.utf8'])
+
+To disable ``default_filters`` entirely, set it to an empty
+list:
+
+.. sourcecode:: python
+
+ t = TemplateLookup(directories=['/tmp'], default_filters=[])
+
+Any string name can be added to ``default_filters`` where it
+will be added to all expressions as a filter. The filters are
+applied from left to right, meaning the leftmost filter is
+applied first.
+
+.. sourcecode:: python
+
+ t = Template(templatetext, default_filters=['unicode', 'myfilter'])
+
+To ease the usage of ``default_filters`` with custom filters,
+you can also add imports (or other code) to all templates using
+the ``imports`` argument:
+
+.. sourcecode:: python
+
+ t = TemplateLookup(directories=['/tmp'],
+ default_filters=['unicode', 'myfilter'],
+ imports=['from mypackage import myfilter'])
+
+The above will generate templates something like this:
+
+.. sourcecode:: python
+
+ # ....
+ from mypackage import myfilter
+
+ def render_body(context):
+ context.write(myfilter(unicode("some text")))
+
+Turning off Filtering with the "n" filter
+------------------------------------------
+
+In all cases the special ``n`` filter, used locally within an
+expression, will **disable** all filters declared in the
+``<%page>`` tag as well ``default_filters``. Such as:
+
+.. sourcecode:: mako
+
+ ${'myexpression' | n}
+
+Will render ``myexpression`` with no filtering of any kind, and
+
+.. sourcecode:: mako
+
+ ${'myexpression' | n, trim}
+
+will render ``myexpression`` using the ``trim`` filter only.
+
+Filtering Defs
+=================
+
+The ``%def`` tag has a filter argument which will apply the
+given list of filter functions to the output of the ``%def``:
+
+.. sourcecode:: mako
+
+ <%def name="foo()" filter="h, trim">
+ <b>this is bold</b>
+ </%def>
+
+When the filter attribute is applied to a def as above, the def
+is automatically **buffered** as well. This is described next.
+
+Buffering
+==========
+
+One of Mako's central design goals is speed. To this end, all of
+the textual content within a template and its various callables
+is by default piped directly to the single buffer that is stored
+within the ``Context`` object. While this normally is easy to
+miss, it has certain side effects. The main one is that when you
+call a def using the normal expression syntax, i.e.
+``${somedef()}``, it may appear that the return value of the
+function is the content it produced, which is then delivered to
+your template just like any other expression substitution,
+except that normally, this is not the case; the return value of
+``${somedef()}`` is simply the empty string ``''``. By the time
+you receive this empty string, the output of ``somedef()`` has
+been sent to the underlying buffer.
+
+You may not want this effect, if for example you are doing
+something like this:
+
+.. sourcecode:: mako
+
+ ${" results " + somedef() + " more results "}
+
+If the ``somedef()`` function produced the content "``somedef's
+results``", the above template would produce this output:
+
+.. sourcecode:: html
+
+ somedef's results results more results
+
+This is because ``somedef()`` fully executes before the
+expression returns the results of its concatenation; the
+concatenation in turn receives just the empty string as its
+middle expression.
+
+Mako provides two ways to work around this. One is by applying
+buffering to the ``%def`` itself:
+
+.. sourcecode:: mako
+
+ <%def name="somedef()" buffered="True">
+ somedef's results
+ </%def>
+
+The above definition will generate code similar to this:
+
+.. sourcecode:: python
+
+ def somedef():
+ context.push_buffer()
+ try:
+ context.write("somedef's results")
+ finally:
+ buf = context.pop_buffer()
+ return buf.getvalue()
+
+So that the content of ``somedef()`` is sent to a second buffer,
+which is then popped off the stack and its value returned. The
+speed hit inherent in buffering the output of a def is also
+apparent.
+
+Note that the ``filter`` argument on %def also causes the def to
+be buffered. This is so that the final content of the %def can
+be delivered to the escaping function in one batch, which
+reduces method calls and also produces more deterministic
+behavior for the filtering function itself, which can possibly
+be useful for a filtering function that wishes to apply a
+transformation to the text as a whole.
+
+The other way to buffer the output of a def or any Mako callable
+is by using the built-in ``capture`` function. This function
+performs an operation similar to the above buffering operation
+except it is specified by the caller.
+
+.. sourcecode:: mako
+
+ ${" results " + capture(somedef) + " more results "}
+
+Note that the first argument to the ``capture`` function is
+**the function itself**, not the result of calling it. This is
+because the ``capture`` function takes over the job of actually
+calling the target function, after setting up a buffered
+environment. To send arguments to the function, just send them
+to ``capture`` instead:
+
+.. sourcecode:: mako
+
+ ${capture(somedef, 17, 'hi', use_paging=True)}
+
+The above call is equivalent to the unbuffered call:
+
+.. sourcecode:: mako
+
+ ${somedef(17, 'hi', use_paging=True)}
+
+Decorating
+===========
+
+This is a feature that's new as of version 0.2.5. Somewhat like
+a filter for a %def but more flexible, the ``decorator``
+argument to ``%def`` allows the creation of a function that will
+work in a similar manner to a Python decorator. The function can
+control whether or not the function executes. The original
+intent of this function is to allow the creation of custom cache
+logic, but there may be other uses as well.
+
+``decorator`` is intended to be used with a regular Python
+function, such as one defined in a library module. Here we'll
+illustrate the python function defined in the template for
+simplicities' sake:
+
+.. sourcecode:: mako
+
+ <%!
+ def bar(fn):
+ def decorate(context, *args, **kw):
+ context.write("BAR")
+ fn(*args, **kw)
+ context.write("BAR")
+ return ''
+ return decorate
+ %>
+
+ <%def name="foo()" decorator="bar">
+ this is foo
+ </%def>
+
+ ${foo()}
+
+The above template will return, with more whitespace than this,
+``"BAR this is foo BAR"``. The function is the render callable
+itself (or possibly a wrapper around it), and by default will
+write to the context. To capture its output, use the ``capture``
+callable in the ``mako.runtime`` module (available in templates
+as just ``runtime``):
+
+.. sourcecode:: mako
+
+ <%!
+ def bar(fn):
+ def decorate(context, *args, **kw):
+ return "BAR" + runtime.capture(context, fn, *args, **kw) + "BAR"
+ return decorate
+ %>
+
+ <%def name="foo()" decorator="bar">
+ this is foo
+ </%def>
+
+ ${foo()}
+
+The decorator can be used with top-level defs as well as nested
+defs. Note that when calling a top-level def from the
+``Template`` api, i.e. ``template.get_def('somedef').render()``,
+the decorator has to write the output to the ``context``, i.e.
+as in the first example. The return value gets discarded.
diff --git a/doc/build/inheritance.rst b/doc/build/inheritance.rst
index 8b13789..c876864 100644
--- a/doc/build/inheritance.rst
+++ b/doc/build/inheritance.rst
@@ -1 +1,321 @@
+.. _inheritance_toplevel:
+===========
+Inheritance
+===========
+
+Using template inheritance, two or more templates can organize
+themselves into an **inheritance chain**, where content and
+functions from all involved templates can be intermixed. The
+general paradigm of template inheritance is this: if a template
+``A`` inherits from template ``B``, then template ``A`` agrees
+to send the executional control to template ``B`` at runtime
+(``A`` is called the **inheriting** template). Template ``B``,
+the **inherited** template, then makes decisions as to what
+resources from ``A`` shall be executed.
+
+In practice, it looks like this. Heres a hypothetical inheriting
+template, ``index.html``:
+
+.. sourcecode:: mako
+
+ ## index.html
+ <%inherit file="base.html"/>
+
+ <%def name="header()">
+ this is some header content
+ </%def>
+
+ this is the body content.
+
+And ``base.html``, the inherited template:
+
+.. sourcecode:: mako
+
+ ## base.html
+ <html>
+ <body>
+ <div class="header">
+ ${self.header()}
+ </div>
+
+ ${self.body()}
+
+ <div class="footer">
+ ${self.footer()}
+ </div>
+ </body>
+ </html>
+
+ <%def name="footer()">
+ this is the footer
+ </%def>
+
+Here is a breakdown of the execution:
+
+* When ``index.html`` is rendered, control immediately passes to
+ ``base.html``.
+* ``base.html`` then renders the top part of an HTML document,
+ then calls the method ``header()`` off of a built in namespace
+ called ``self`` (this namespace was first introduced in the
+ Namespaces chapter in
+ :ref:`namespace_self`). Since
+ ``index.html`` is the topmost template and also defines a def
+ called ``header()``, its this ``header()`` def that gets
+ executed.
+* Control comes back to ``base.html``. Some more HTML is
+ rendered.
+* ``base.html`` executes ``self.body()``. The ``body()``
+ function on all template-based namespaces refers to the main
+ body of the template, therefore the main body of
+ ``index.html`` is rendered.
+* Control comes back to ``base.html``. More HTML is rendered,
+ then the ``self.footer()`` expression is invoked.
+* The ``footer`` def is only defined in ``base.html``, so being
+ the topmost definition of ``footer``, its the one that
+ executes. If ``index.html`` also specified ``footer``, then
+ its version would **override** that of the base.
+* ``base.html`` finishes up rendering its HTML and the template
+ is complete, producing:
+
+.. sourcecode:: html
+
+ <html>
+ <body>
+ <div class="header">
+ this is some header content
+ </div>
+
+ this is the body content.
+
+ <div class="footer">
+ this is the footer
+ </div>
+ </body>
+ </html>
+
+...and that is template inheritance in a nutshell. The main idea
+is that the methods that you call upon ``self`` always
+correspond to the topmost definition of that method. Very much
+the way ``self`` works in a Python class, even though Mako is
+not actually using Python class inheritance to implement this
+functionality. (Mako doesn't take the "inheritance" metaphor too
+seriously; while useful to setup some commonly recognized
+semantics, a textual template is not very much like an
+object-oriented class construct in practice).
+
+Using the "next" namespace to produce content wrapping
+=======================================================
+
+Sometimes you have an inheritance chain that spans more than two
+templates. Or maybe you don't, but youd like to build your
+system such that extra inherited templates can be inserted in
+the middle of a chain where they would be smoothly integrated.
+If each template wants to define its layout just within its main
+body, you can't just call ``self.body()`` to get at the
+inheriting template's body, since that is only the topmost body.
+To get at the body of the *next* template, you call upon the
+namespace ``next``, which is the namespace of the template
+**immediately following** the current template.
+
+Lets change the line in ``base.html`` which calls upon
+``self.body()`` to instead call upon ``next.body()``:
+
+.. sourcecode:: mako
+
+ ## base.html
+ <html>
+ <body>
+ <div class="header">
+ ${self.header()}
+ </div>
+
+ ${next.body()}
+
+ <div class="footer">
+ ${self.footer()}
+ </div>
+ </body>
+ </html>
+
+ <%def name="footer()">
+ this is the footer
+ </%def>
+
+Lets also add an intermediate template called ``layout.html``,
+which inherits from ``base.html``:
+
+.. sourcecode:: mako
+
+ ## layout.html
+ <%inherit file="base.html"/>
+ <ul>
+ ${self.toolbar()}
+ </ul>
+ <div class="mainlayout">
+ ${next.body()}
+ </div>
+
+ <%def name="toolbar()">
+ <li>selection 1</li>
+ <li>selection 2</li>
+ <li>selection 3</li>
+ </%def>
+
+And finally change ``index.html`` to inherit from
+``layout.html`` instead:
+
+.. sourcecode:: mako
+
+ ## index.html
+ <%inherit file="layout.html"/>
+
+ ## .. rest of template
+
+In this setup, each call to ``next.body()`` will render the body
+of the next template in the inheritance chain (which can be
+written as ``base.html -> layout.html -> index.html``). Control
+is still first passed to the bottommost template ``base.html``,
+and ``self`` still references the topmost definition of any
+particular def.
+
+The output we get would be:
+
+.. sourcecode:: html
+
+ <html>
+ <body>
+ <div class="header">
+ this is some header content
+ </div>
+
+ <ul>
+ <li>selection 1</li>
+ <li>selection 2</li>
+ <li>selection 3</li>
+ </ul>
+
+ <div class="mainlayout">
+ this is the body content.
+ </div>
+
+ <div class="footer">
+ this is the footer
+ </div>
+ </body>
+ </html>
+
+So above, we have the ``<html>``, ``<body>`` and
+``header``/``footer`` layout of ``base.html``, we have the
+``<ul>`` and ``mainlayout`` section of ``layout.html``, and the
+main body of ``index.html`` as well as its overridden ``header``
+def. The ``layout.html`` template is inserted into the middle of
+the chain without ``base.html`` having to change anything.
+Without the ``next`` namespace, only the main body of
+``index.html`` could be used; there would be no way to call
+``layout.html``'s body content.
+
+Using the "parent" namespace to augment defs
+=============================================
+
+Lets now look at the other inheritance-specific namespace, the
+opposite of ``next`` called ``parent``. ``parent`` is the
+namespace of the template **immediately preceding** the current
+template. What is most useful about this namespace is the
+methods within it which can be accessed within overridden
+versions of those methods. This is not as hard as it sounds and
+is very much like using the ``super`` keyword in Python. Lets
+modify ``index.html`` to augment the list of selections provided
+by the ``toolbar`` function in ``layout.html``:
+
+.. sourcecode:: mako
+
+ ## index.html
+ <%inherit file="layout.html"/>
+
+ <%def name="header()">
+ this is some header content
+ </%def>
+
+ <%def name="toolbar()">
+ ## call the parent's toolbar first
+ ${parent.toolbar()}
+ <li>selection 4</li>
+ <li>selection 5</li>
+ </%def>
+
+ this is the body content.
+
+Above, we implemented a ``toolbar()`` function, which is meant
+to override the definition of ``toolbar`` within the inherited
+template ``layout.html``. However, since we want the content
+from that of ``layout.html`` as well, we call it via the
+``parent`` namespace whenever we want it's content, in this case
+before we add our own selections. So the output for the whole
+thing is now:
+
+.. sourcecode:: html
+
+ <html>
+ <body>
+ <div class="header">
+ this is some header content
+ </div>
+
+ <ul>
+ <li>selection 1</li>
+ <li>selection 2</li>
+ <li>selection 3</li>
+ <li>selection 4</li>
+ <li>selection 5</li>
+ </ul>
+
+ <div class="mainlayout">
+ this is the body content.
+ </div>
+
+ <div class="footer">
+ this is the footer
+ </div>
+ </body>
+ </html>
+
+and you're now a template inheritance ninja !
+
+Inheritable Attributes
+======================
+
+The ``attr`` accessor of the :class:`.Namespace` object allows access
+to module level variables declared in a template. By accessing
+``self.attr``, you can access regular attributes from the
+inheritance chain as declared in ``<%! %>`` sections. Such as:
+
+.. sourcecode:: mako
+
+ <%!
+ class_ = "grey"
+ %>
+
+ <div class="${self.attr.class_}">
+ ${self.body()}
+ </div>
+
+If a an inheriting template overrides ``class_`` to be
+``white``, as in:
+
+.. sourcecode:: mako
+
+ <%!
+ class_ = "white"
+ %>
+ <%inherit file="parent.html"/>
+
+ This is the body
+
+You'll get output like:
+
+.. sourcecode:: html
+
+ <div class="white">
+ This is the body
+ </div>
diff --git a/doc/build/namespaces.rst b/doc/build/namespaces.rst
index 8b13789..5939020 100644
--- a/doc/build/namespaces.rst
+++ b/doc/build/namespaces.rst
@@ -1 +1,383 @@
+.. _namespaces_toplevel:
+
+==========
+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:
+
+.. sourcecode:: mako
+
+ ## 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``:
+
+.. sourcecode:: mako
+
+ ## 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
+:class:`.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.
+
+.. sourcecode:: mako
+
+ <%namespace file="components.html" import="comp1, comp2"/>
+
+ Heres comp1: ${comp1()}
+ Heres comp2: ${comp2(x=5)}
+
+``import`` also supports the "*" operator:
+
+.. sourcecode:: mako
+
+ <%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:
+
+.. sourcecode:: mako
+
+ <%namespace name="dyn" file="${context['namespace_name']}"/>
+
+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:
+
+.. sourcecode:: mako
+
+ ${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:
+
+.. sourcecode:: mako
+
+ <%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:
+
+.. sourcecode:: mako
+
+ <%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":
+
+.. sourcecode:: mako
+
+ <%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:
+
+.. sourcecode:: mako
+
+ <%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 :ref:`defs_with_content`.
+
+.. _namespaces_python_modules:
+
+Namespaces from Regular Python Modules
+========================================
+
+Namespaces can also import regular Python functions from
+modules. These callables need to take at least one argument,
+``context``, an instance of :class:`.Context`. A module file
+``some/module.py`` might contain the callable:
+
+.. sourcecode:: python
+
+ def my_tag(context):
+ context.write("hello world")
+ return ''
+
+A template can use this module via:
+
+.. sourcecode:: mako
+
+ <%namespace name="hw" module="some.module"/>
+
+ ${hw.my_tag()}
+
+Note that the ``context`` argument is not needed in the call;
+the :class:`.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 :meth:`.Context.write` within its body.
+
+If your def is to be called in an "embedded content" context,
+that is as described in :ref:`defs_with_content`, you should use
+the :func:`.supports_caller` decorator, which will ensure that Mako
+will ensure the correct "caller" variable is available when your
+def is called, supporting embedded content:
+
+.. sourcecode:: python
+
+ 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 :func:`.capture` function,
+which accepts the "context" as its first argument:
+
+.. sourcecode:: python
+
+ 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")
+
+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:
+
+.. sourcecode:: mako
+
+ ## define a namespace
+ <%namespace name="stuff">
+ <%def name="comp1()">
+ comp1
+ </%def>
+ </%namespace>
+
+ ## then call it
+ ${stuff.comp1()}
+
+.. _namespaces_body:
+
+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:
+
+.. sourcecode:: mako
+
+ <%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 :meth:`~.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:
+
+.. sourcecode:: mako
+
+ ${self.body(5, y=10, someval=15, delta=7)}
+
+The :class:`.Context` object also supplies a :attr:`~.Context.kwargs` accessor, for
+cases when youd like to pass along whatever is in the context to
+a ``body()`` callable:
+
+.. sourcecode:: mako
+
+ ${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 :ref:`inheritance_toplevel`.
+
+.. _namespaces_builtin:
+
+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
+:ref:`inheritance_toplevel`.
+
+.. _namespace_local:
+
+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.
+
+.. _namespace_self:
+
+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
+:ref:`inheritance_toplevel`.
+
+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``.
+
+.. sourcecode:: mako
+
+ ## 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.
+
+API Reference
+==============
+
+.. autoclass:: mako.runtime.Namespace
+ :show-inheritance:
+ :members:
+
+ .. py:attribute:: attr
+
+ allows access module level attributes by name. This
+ accessor allows templates to supply "scalar" attributes which
+ are particularly handy in inheritance relationships. See the
+ example in :ref:`inheritance_toplevel`.
+
+ .. py:attribute:: module
+
+ the Python module referenced by this Namespace.
+ If the namespace references a :class:`.Template`, then this module
+ is the equivalent of ``template.module``, i.e. the generated
+ module for the template.
+
+ .. py:attribute:: 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.
+
+ .. py:attribute:: template
+
+ the :class:`.Template` object referenced by this
+ :class:`.Namespace`, if any.
+
+ .. py:attribute:: uri
+
+ the uri for this Namespace's template (i.e. whatever
+ was sent to :meth:`.TemplateLookup.get_template()`). This is the equivalent
+ of :attr:`Template.uri`.
+
+ .. py:attribute:: context
+
+ The :class:`.Context` object for this namespace.
+ Namespaces are often created with copies of contexts that
+ contain slightly different data, particularly in inheritance
+ scenarios. Using the :class:`.Context` off of a :class:`.Namespace` one
+ can traverse an entire chain of templates that inherit from
+ one-another.
+
+.. autofunction:: mako.runtime.supports_caller
+
+.. autofunction:: mako.runtime.capture
diff --git a/doc/build/runtime.rst b/doc/build/runtime.rst
index 8b13789..8db081a 100644
--- a/doc/build/runtime.rst
+++ b/doc/build/runtime.rst
@@ -1 +1,238 @@
+.. _runtime_toplevel:
+
+=============================
+The Mako Runtime Environment
+=============================
+
+This section describes a little bit about the objects and
+built-in functions that are available in templates.
+
+Context
+=======
+
+The :class:`.Context` 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 ``StringIO`` 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 :meth:`~.Template.render` function and
+some built-in variables provided by Mako's runtime environment.
+
+The Buffer
+----------
+
+The buffer is stored within the :class:`.Context`, and writing
+to it is achieved by calling :meth:`.Context.write`. You usually
+don't need to care about this as all text within a template, as
+well as all expressions provided by ``${}``, 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
+:ref:`filtering_toplevel`, or if you want to programmatically
+send content to the output stream, such as within a ``<% %>``
+block.
+
+.. sourcecode:: mako
+
+ <%
+ context.write("some programmatic text")
+ %>
+
+The actual buffer may or may not be the original buffer sent to
+the :class:`.Context` object, as various filtering/caching
+scenarios may "push" a new buffer onto the context's underlying
+buffer stack. For this reason, just stick with
+:meth:`.Context.write` and content will always go to the topmost
+buffer.
+
+Context Variables
+------------------
+
+When your template is compiled into a Python module, the body
+content is enclosed within a Python function called
+``render_body``. 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 ``render_`` (i.e. ``render_mydef``).
+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
+:class:`.Context` 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
+:class:`.Context`.
+
+* **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 ``UNDEFINED``, or if the ``strict_undefined=True`` flag
+ is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global
+ variable with the class ``mako.runtime.Undefined``. The
+ ``UNDEFINED`` object throws an error when you call ``str()`` on
+ it, which is what happens if you try to use it in an
+ expression.
+* **UNDEFINED makes it hard for me to find what name is missing** - An alternative
+ introduced in version 0.3.6 is to specify the option
+ ``strict_undefined=True``
+ to the :class:`.Template` or :class:`.TemplateLookup`. This will cause
+ any non-present variables to raise an immediate ``NameError``
+ which includes the name of the variable in its message
+ when :meth:`~.Template.render` is called - ``UNDEFINED`` is not used.
+* **Why not just return None?** Using ``UNDEFINED``, or
+ raising a ``NameError`` is more
+ explicit and allows differentiation between a value of ``None``
+ that was explicitly passed to the :class:`.Context` 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 ``UNDEFINED``
+ is a singleton object just like Python's ``True`` or ``False``,
+ you can use the ``is`` operator to check for it:
+
+ .. sourcecode:: mako
+
+ % if someval is UNDEFINED:
+ someval is: no value
+ % else:
+ someval is: ${someval}
+ % endif
+
+Another facet of the :class:`.Context` is that its dictionary of
+variables is **immutable**. Whatever is set when
+:meth:`~.Template.render` 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 :class:`.Context` object, which
+get sent to various elements of the template and inheriting
+templates used in an execution. So changing the value in your
+local :class:`.Context` will not necessarily make that value
+available in other parts of the template's execution. Examples
+of where Mako creates copies of the :class:`.Context` 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 ``parent`` and ``next``, which
+are all stored in unique :class:`.Context` instances).
+
+* **So what if I want to set values that are global to everyone
+ within a template request?** - All you have to do is provide a
+ dictionary to your :class:`.Context` when the template first
+ runs, and everyone can just get/set variables from that. Lets
+ say its called ``attributes``.
+
+ Running the template looks like:
+
+ .. sourcecode:: python
+
+ output = template.render(attributes={})
+
+ Within a template, just reference the dictionary:
+
+ .. sourcecode:: mako
+
+ <%
+ attributes['foo'] = 'bar'
+ %>
+ 'foo' attribute is: ${attributes['foo']}
+
+* **Why can't "attributes" be a built-in feature of the
+ Context?** - This is an area where Mako is trying to make as
+ few decisions about your application as it possibly can.
+ Perhaps you don't want your templates to use this technique of
+ assigning and sharing data, or perhaps you have a different
+ notion of the names and kinds of data structures that should
+ be passed around. Once again Mako would rather ask the user to
+ be explicit.
+
+Context Methods and Accessors
+------------------------------
+
+Significant members off of :class:`.Context` include:
+
+* ``context[key]`` / ``context.get(key, default=None)`` -
+ 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 ``get`` 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 ``KeyError``.
+* ``keys()`` - all the names defined within this context.
+* ``kwargs`` - 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.:
+
+.. sourcecode:: mako
+
+ ${next.body(**context.kwargs)}
+
+* ``write(text)`` - write some text to the current output
+ stream.
+* ``lookup`` - returns the :class:`.TemplateLookup` instance that is
+ used for all file-lookups within the current execution (even
+ though individual :class:`.Template` instances can conceivably have
+ different instances of a :class:`.TemplateLookup`, only the
+ :class:`.TemplateLookup` of the originally-called :class:`.Template` gets
+ used in a particular execution).
+
+All the built-in names
+======================
+
+A one-stop shop for all the names Mako defines. Most of these
+names are instances of :class:`.Namespace`, which are described
+in the next section, :ref:`namespaces_toplevel`. Also, most of
+these names other than :class:`.Context` and ``UNDEFINED`` are
+also present *within* the :class:`.Context` itself.
+
+* ``local`` - the namespace of the current template, described
+ in :ref:`namespaces_builtin`.
+* ``self`` - the namespace of the topmost template in an
+ inheritance chain (if any, otherwise the same as ``local``),
+ mostly described in :ref:`inheritance_toplevel`.
+* ``parent`` - the namespace of the parent template in an
+ inheritance chain (otherwise undefined); see
+ :ref:`inheritance_toplevel`.
+* ``next`` - the namespace of the next template in an
+ inheritance chain (otherwise undefined); see
+ :ref:`inheritance_toplevel`.
+* ``caller`` - a "mini" namespace created when using the
+ ``<%call>`` tag to define a "def call with content"; described
+ in :ref:`defs_with_content`.
+* ``capture`` - a function that calls a given def and captures
+ its resulting content into a string, which is returned. Usage
+ is described in :ref:`filtering_toplevel`.
+* ``UNDEFINED`` - a global singleton that is applied to all
+ otherwise uninitialized template variables that were not
+ located within the :class:`.Context` when rendering began,
+ unless the :class:`.Template` flag ``strict_undefined``
+ is set to ``True``. ``UNDEFINED`` is
+ an instance of :class:`.Undefined`, and raises an
+ exception when its ``__str__()`` method is called.
+* ``pageargs`` - this is a dictionary which is present in a
+ template which does not define any \**kwargs section in its
+ ``<%page>`` tag. All keyword arguments sent to the ``body()``
+ 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
+ :ref:`namespaces_body`.
+
+API Reference
+==============
+
+.. autoclass:: mako.runtime.Context
+ :show-inheritance:
+ :members:
+
+.. autoclass:: mako.runtime.Undefined
+ :show-inheritance:
+
+
diff --git a/doc/build/syntax.rst b/doc/build/syntax.rst
index 4207570..1e5ecfb 100644
--- a/doc/build/syntax.rst
+++ b/doc/build/syntax.rst
@@ -193,8 +193,9 @@ pure-Python functions you might want to declare:
%>
Any number of ``<%! %>`` blocks can be declared anywhere in a
-template; they will be rendered in the resulting module in the
-order that they appear.
+template; they will be rendered in the resulting module
+in a single contiguous block above all render callables,
+in the order in which they appear in the source template.
Tags
====
diff --git a/doc/build/unicode.rst b/doc/build/unicode.rst
index 1615e7c..771ca4b 100644
--- a/doc/build/unicode.rst
+++ b/doc/build/unicode.rst
@@ -3,3 +3,333 @@
===================
The Unicode Chapter
===================
+
+The Python language supports two ways of representing what we
+know as "strings", i.e. series of characters. In Python 2, the
+two types are ``string`` and ``unicode``, and in Python 3 they are
+``bytes`` and ``string``. A key aspect of the Python 2 ``string`` and
+Python 3 ``bytes`` types are that they contain no information
+regarding what **encoding** the data is stored in. For this
+reason they were commonly referred to as **byte strings** on
+Python 2, and Python 3 makes this name more explicit. The
+origins of this come from Python's background of being developed
+before the Unicode standard was even available, back when
+strings were C-style strings and were just that, a series of
+bytes. Strings that had only values below 128 just happened to
+be **ascii** strings and were printable on the console, whereas
+strings with values above 128 would produce all kinds of
+graphical characters and bells.
+
+Contrast the "bytestring" types with the "unicode/string" type.
+Objects of this type are created whenever you say something like
+``u"hello world"`` (or in Python 3, just ``"hello world"``). In this
+case, Python represents each character in the string internally
+using multiple bytes per character (something similar to
+UTF-16). Whats important is that when using the
+``unicode``/``string`` type to store strings, Python knows the
+data's encoding; its in its own internal format. Whereas when
+using the ``string``/``bytes`` type, it does not.
+
+When Python 2 attempts to treat a byte-string as a string, which
+means its attempting to compare/parse its characters, to coerce
+it into another encoding, or to decode it to a unicode object,
+it has to guess what the encoding is. In this case, it will
+pretty much always guess the encoding as ``ascii``...and if the
+bytestring contains bytes above value 128, you'll get an error.
+Python 3 eliminates much of this confusion by just raising an
+error unconditionally if a bytestring is used in a
+character-aware context.
+
+There is one operation that Python *can* do with a non-ascii
+bytestring, and its a great source of confusion: it can dump the
+bytestring straight out to a stream or a file, with nary a care
+what the encoding is. To Python, this is pretty much like
+dumping any other kind of binary data (like an image) to a
+stream somewhere. In Python 2, it is common to see programs that
+embed all kinds of international characters and encodings into
+plain byte-strings (i.e. using ``"hello world"`` style literals)
+can fly right through their run, sending reams of strings out to
+whereever they are going, and the programmer, seeing the same
+output as was expressed in the input, is now under the illusion
+that his or her program is Unicode-compliant. In fact, their
+program has no unicode awareness whatsoever, and similarly has
+no ability to interact with libraries that *are* unicode aware.
+Python 3 makes this much less likely by defaulting to unicode as
+the storage format for strings.
+
+The "pass through encoded data" scheme is what template
+languages like Cheetah and earlier versions of Myghty do by
+default. Mako as of version 0.2 also supports this mode of
+operation when using Python 2, using the "disable_unicode=True"
+flag. However, when using Mako in its default mode of
+unicode-aware, it requires explicitness when dealing with
+non-ascii encodings. Additionally, if you ever need to handle
+unicode strings and other kinds of encoding conversions more
+intelligently, the usage of raw bytestrings quickly becomes a
+nightmare, since you are sending the Python interpreter
+collections of bytes for which it can make no intelligent
+decisions with regards to encoding. In Python 3 Mako only allows
+usage of native, unicode strings.
+
+In normal Mako operation, all parsed template constructs and
+output streams are handled internally as Python ``unicode``
+objects. Its only at the point of :meth:`~.Template.render` that this unicode
+stream may be rendered into whatever the desired output encoding
+is. The implication here is that the template developer must
+ensure that the encoding of all non-ascii templates is explicit
+(still required in Python 3), that all non-ascii-encoded
+expressions are in one way or another converted to unicode (not
+much of a burden in Python 3), and that the output stream of the
+template is handled as a unicode stream being encoded to some
+encoding (still required in Python 3).
+
+Specifying the Encoding of a Template File
+===========================================
+
+This is the most basic encoding-related setting, and it is
+equivalent to Python's "magic encoding comment", as described in
+`pep-0263 <http://www.python.org/dev/peps/pep-0263/>`_. Any
+template that contains non-ascii characters requires that this
+comment be present so that Mako can decode to unicode (and also
+make usage of Python's AST parsing services). Mako's lexer will
+use this encoding in order to convert the template source into a
+``unicode`` object before continuing its parsing:
+
+.. sourcecode:: mako
+
+ ## -*- coding: utf-8 -*-
+
+ Alors vous imaginez ma surprise, au lever du jour, quand
+ une drôle de petite voix m’a réveillé. Elle disait:
+ « S’il vous plaît… dessine-moi un mouton! »
+
+For the picky, the regular expression used is derived from that
+of the abovementioned pep:
+
+.. sourcecode:: python
+
+ #.*coding[:=]\s*([-\w.]+).*\n
+
+The lexer will convert to unicode in all cases, so that if any
+characters exist in the template that are outside of the
+specified encoding (or the default of ``ascii``), the error will
+be immediate.
+
+As an alternative, the template encoding can be specified
+programmatically to either :class:`.Template` or :class:`.TemplateLookup` via
+the ``input_encoding`` parameter:
+
+.. sourcecode:: python
+
+ t = TemplateLookup(directories=['./'], input_encoding='utf-8')
+
+The above will assume all located templates specify ``utf-8``
+encoding, unless the template itself contains its own magic
+encoding comment, which takes precedence.
+
+Handling Expressions
+=====================
+
+The next area that encoding comes into play is in expression
+constructs. By default, Mako's treatment of an expression like
+this:
+
+.. sourcecode:: mako
+
+ ${"hello world"}
+
+looks something like this:
+
+.. sourcecode:: python
+
+ context.write(unicode("hello world"))
+
+In Python 3, its just:
+
+.. sourcecode:: python
+
+ context.write(str("hello world"))
+
+That is, **the output of all expressions is run through the
+``unicode`` builtin**. This is the default setting, and can be
+modified to expect various encodings. The ``unicode`` step serves
+both the purpose of rendering non-string expressions into
+strings (such as integers or objects which contain ``__str()__``
+methods), and to ensure that the final output stream is
+constructed as a unicode object. The main implication of this is
+that **any raw bytestrings that contain an encoding other than
+ascii must first be decoded to a Python unicode object**. It
+means you can't say this in Python 2:
+
+.. sourcecode:: mako
+
+ ${"voix m’a réveillé."} ## error in Python 2!
+
+You must instead say this:
+
+.. sourcecode:: mako
+
+ ${u"voix m’a réveillé."} ## OK !
+
+Similarly, if you are reading data from a file that is streaming
+bytes, or returning data from some object that is returning a
+Python bytestring containing a non-ascii encoding, you have to
+explcitly decode to unicode first, such as:
+
+.. sourcecode:: mako
+
+ ${call_my_object().decode('utf-8')}
+
+Note that filehandles acquired by ``open()`` in Python 3 default
+to returning "text", that is the decoding is done for you. See
+Python 3's documentation for the ``open()`` builtin for details on
+this.
+
+If you want a certain encoding applied to *all* expressions,
+override the ``unicode`` builtin with the ``decode`` builtin at the
+:class:`.Template` or :class:`.TemplateLookup` level:
+
+.. sourcecode:: python
+
+ t = Template(templatetext, default_filters=['decode.utf8'])
+
+Note that the built-in ``decode`` object is slower than the
+``unicode`` function, since unlike ``unicode`` its not a Python
+builtin, and it also checks the type of the incoming data to
+determine if string conversion is needed first.
+
+The ``default_filters`` argument can be used to entirely customize
+the filtering process of expressions. This argument is described
+in :ref:`filtering_default_filters`.
+
+Defining Output Encoding
+=========================
+
+Now that we have a template which produces a pure unicode output
+stream, all the hard work is done. We can take the output and do
+anything with it.
+
+As stated in the "Usage" chapter, both :class:`.Template` and
+:class:`.TemplateLookup` accept ``output_encoding`` and ``encoding_errors``
+parameters which can be used to encode the output in any Python
+supported codec:
+
+.. sourcecode:: 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()
+
+:meth:`~.Template.render` will return a ``bytes`` object in Python 3 if an output
+encoding is specified. By default it performs no encoding and
+returns a native string.
+
+:meth:`~.Template.render_unicode` will return the template output as a Python
+``unicode`` object (or ``string`` in Python 3):
+
+.. sourcecode:: python
+
+ print mytemplate.render_unicode()
+
+The above method disgards the output encoding keyword argument;
+you can encode yourself by saying:
+
+.. sourcecode:: python
+
+ print mytemplate.render_unicode().encode('utf-8', 'replace')
+
+Buffer Selection
+-----------------
+
+Mako does play some games with the style of buffering used
+internally, to maximize performance. Since the buffer is by far
+the most heavily used object in a render operation, its
+important!
+
+When calling :meth:`~.Template.render` on a template that does not specify any
+output encoding (i.e. its ``ascii``), Python's ``cStringIO`` module,
+which cannot handle encoding of non-ascii ``unicode`` objects
+(even though it can send raw bytestrings through), is used for
+buffering. Otherwise, a custom Mako class called
+``FastEncodingBuffer`` is used, which essentially is a super
+dumbed-down version of ``StringIO`` that gathers all strings into
+a list and uses ``u''.join(elements)`` to produce the final output
+- its markedly faster than ``StringIO``.
+
+Saying to Heck with it: Disabling the usage of Unicode entirely
+================================================================
+
+Some segements of Mako's userbase choose to make no usage of
+Unicode whatsoever, and instead would prefer the "passthru"
+approach; all string expressions in their templates return
+encoded bytestrings, and they would like these strings to pass
+right through. The only advantage to this approach is that
+templates need not use ``u""`` for literal strings; there's an
+arguable speed improvement as well since raw bytestrings
+generally perform slightly faster than unicode objects in
+Python. For these users, assuming they're sticking with Python
+2, they can hit the ``disable_unicode=True`` flag as so:
+
+.. sourcecode:: python
+
+ # -*- encoding:utf-8 -*-
+ from mako.template import Template
+
+ t = Template("drôle de petite voix m’a réveillé.", disable_unicode=True, input_encoding='utf-8')
+ print t.code
+
+The ``disable_unicode`` mode is strictly a Python 2 thing. It is
+not supported at all in Python 3.
+
+The generated module source code will contain elements like
+these:
+
+.. sourcecode:: python
+
+ # -*- encoding:utf-8 -*-
+ # ...more generated code ...
+
+ def render_body(context,**pageargs):
+ context.caller_stack.push_frame()
+ try:
+ __M_locals = dict(pageargs=pageargs)
+ # SOURCE LINE 1
+ context.write('dr\xc3\xb4le de petite voix m\xe2\x80\x99a r\xc3\xa9veill\xc3\xa9.')
+ return ''
+ finally:
+ context.caller_stack.pop_frame()
+
+Where above that the string literal used within :meth:`.Context.write`
+is a regular bytestring.
+
+When ``disable_unicode=True`` is turned on, the ``default_filters``
+argument which normally defaults to ``["unicode"]`` now defaults
+to ``["str"]`` instead. Setting default_filters to the empty list
+``[]`` can remove the overhead of the ``str`` call. Also, in this
+mode you **cannot** safely call :meth:`~.Template.render_unicode` - you'll get
+unicode/decode errors.
+
+The ``h`` filter (html escape) uses a less performant pure Python
+escape function in non-unicode mode (note that in versions prior
+to 0.3.4, it used cgi.escape(), which has been replaced with a
+function that also escapes single quotes). This because
+MarkupSafe only supports Python unicode objects for non-ascii
+strings.
+
+**Rules for using disable_unicode=True**
+
+* don't use this mode unless you really, really want to and you
+ absolutely understand what you're doing
+* don't use this option just because you don't want to learn to
+ use Unicode properly; we aren't supporting user issues in this
+ mode of operation. We will however offer generous help for the
+ vast majority of users who stick to the Unicode program.
+* Python 3 is unicode by default, and the flag is not available
+ when running on Python 3.
+
+
+
diff --git a/doc/build/usage.rst b/doc/build/usage.rst
index 6c2dd90..4309c8c 100644
--- a/doc/build/usage.rst
+++ b/doc/build/usage.rst
@@ -22,10 +22,10 @@ the :class:`.Template` class::
Above, the text argument to :class:`.Template` is **compiled** into a
Python module representation. This module contains a function
-called :meth:`~.Template.render_body()`, which produces the output of the
+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
-:meth:`~.Template.render_body()` function, capturing the output into a buffer and
+``render_body()`` function, capturing the output into a buffer and
returning its string contents.
@@ -415,18 +415,23 @@ API Documentation
=================
.. autoclass:: mako.template.Template
+ :show-inheritance:
:members:
.. autoclass:: mako.template.DefTemplate
+ :show-inheritance:
:members:
.. autoclass:: mako.lookup.TemplateCollection
+ :show-inheritance:
:members:
.. autoclass:: mako.lookup.TemplateLookup
+ :show-inheritance:
:members:
.. autoclass:: mako.exceptions.RichTraceback
+ :show-inheritance:
.. py:attribute:: error
@@ -466,7 +471,6 @@ API Documentation
.. py:attribute:: reverse_traceback
the traceback list in reverse
-
.. autofunction:: mako.exceptions.html_error_template
diff --git a/mako/lookup.py b/mako/lookup.py
index 15793b7..15848d8 100644
--- a/mako/lookup.py
+++ b/mako/lookup.py
@@ -87,7 +87,7 @@ class TemplateLookup(TemplateCollection):
some_template = lookup.get_template("/index.html")
The :class:`.TemplateLookup` can also be given :class:`.Template` objects
- programattically using :meth:`put_string` or :meth:`put_template`::
+ programatically using :meth:`.put_string` or :meth:`.put_template`::
lookup = TemplateLookup()
lookup.put_string("base.html", '''
@@ -111,7 +111,7 @@ class TemplateLookup(TemplateCollection):
will maintain the size of the collection approximately to the number given.
:param filesystem_checks: When at its default value of ``True``, each
- call to :meth:`get_template()` will compare the filesystem last modified
+ call to :meth:`TemplateLookup.get_template()` will compare the filesystem last modified
time to the time in which an existing :class:`.Template` object was created.
This allows the :class:`.TemplateLookup` to regenerate a new :class:`.Template`
whenever the original source has been updated. Set this to ``False`` for a
diff --git a/mako/runtime.py b/mako/runtime.py
index 863b4e7..0be67fc 100644
--- a/mako/runtime.py
+++ b/mako/runtime.py
@@ -10,7 +10,12 @@ from mako import exceptions, util
import __builtin__, inspect, sys
class Context(object):
- """provides runtime namespace, output buffer, and various callstacks for templates."""
+ """Provides runtime namespace, output buffer, and various callstacks for templates.
+
+ See :ref:`runtime_toplevel` for detail on the usage of :class:`.Context`.
+
+ """
+
def __init__(self, buffer, **data):
self._buffer_stack = [buffer]
self._orig = data # original data, minus the builtins
@@ -29,26 +34,40 @@ class Context(object):
@property
def lookup(self):
+ """Return the :class:`.TemplateLookup` associated
+ with this :class:`.Context`.
+
+ """
return self._with_template.lookup
@property
def kwargs(self):
+ """Return the dictionary of keyword argments associated with this
+ :class:`.Context`.
+
+ """
return self._kwargs.copy()
def push_caller(self, caller):
+ """Pushes a 'caller' callable onto the callstack for this :class:`.Context`."""
+
+
self.caller_stack.append(caller)
def pop_caller(self):
+ """Pops a 'caller' callable onto the callstack for this :class:`.Context`."""
+
del self.caller_stack[-1]
def keys(self):
+ """Return a list of all names established in this :class:`.Context`."""
return self._data.keys()
def __getitem__(self, key):
return self._data[key]
def _push_writer(self):
- """push a capturing buffer onto this Context and return the new Writer function."""
+ """push a capturing buffer onto this Context and return the new writer function."""
buf = util.FastEncodingBuffer()
self._buffer_stack.append(buf)
@@ -74,15 +93,17 @@ class Context(object):
return self._buffer_stack.pop()
def get(self, key, default=None):
+ """Return a value from this :class:`.Context`."""
+
return self._data.get(key, default)
def write(self, string):
- """write a string to this Context's underlying output buffer."""
+ """Write a string to this :class:`.Context` object's underlying output buffer."""
self._buffer_stack[-1].write(string)
def writer(self):
- """return the current writer function"""
+ """Return the current writer function"""
return self._buffer_stack[-1].write
@@ -97,15 +118,19 @@ class Context(object):
c.namespaces = self.namespaces
c.caller_stack = self.caller_stack
return c
+
def locals_(self, d):
- """create a new Context with a copy of this Context's current state, updated with the given dictionary."""
+ """create a new :class:`.Context` with a copy of this
+ :class:`Context`'s current state, updated with the given dictionary."""
+
if len(d) == 0:
return self
c = self._copy()
c._data.update(d)
return c
+
def _clean_inheritance_tokens(self):
- """create a new copy of this Context with tokens related to inheritance state removed."""
+ """create a new copy of this :class:`.Context`. with tokens related to inheritance state removed."""
c = self._copy()
x = c._data
x.pop('self', None)
@@ -130,7 +155,13 @@ class CallerStack(list):
class Undefined(object):
- """represents an undefined value in a template."""
+ """Represents an undefined value in a template.
+
+ All template modules have a constant value
+ ``UNDEFINED`` present which is an instance of this
+ object.
+
+ """
def __str__(self):
raise NameError("Undefined")
def __nonzero__(self):
@@ -151,8 +182,10 @@ class _NSAttr(object):
raise AttributeError(key)
class Namespace(object):
- """provides access to collections of rendering methods, which
- can be local, from other templates, or from imported modules"""
+ """Provides access to collections of rendering methods, which
+ can be local, from other templates, or from imported modules.
+
+ """
def __init__(self, name, context, module=None,
template=None, templateuri=None,
@@ -204,9 +237,25 @@ class Namespace(object):
return self._attr
def get_namespace(self, uri):
- """return a namespace corresponding to the given template uri.
+ """Return a :class:`.Namespace` corresponding to the given uri.
- if a relative uri, it is adjusted to that of the template of this namespace"""
+ If the given uri is a relative uri (i.e. it does not
+ contain ia 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 :ref:`namespace_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
+ evaulated 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.
+
+ """
key = (self, uri)
if self.context.namespaces.has_key(key):
return self.context.namespaces[key]
@@ -286,7 +335,11 @@ class Namespace(object):
raise AttributeError("Namespace '%s' has no member '%s'" % (self.name, key))
def supports_caller(func):
- """apply a caller_stack compatibility decorator to a plain Python function."""
+ """Apply a caller_stack compatibility decorator to a plain Python function.
+
+ See the example in :ref:`namespaces_python_modules`.
+
+ """
def wrap_stackframe(context, *args, **kwargs):
context.caller_stack._push_frame()
@@ -297,7 +350,11 @@ def supports_caller(func):
return wrap_stackframe
def capture(context, callable_, *args, **kwargs):
- """execute the given template def, capturing the output into a buffer."""
+ """Execute the given template def, capturing the output into a buffer.
+
+ See the example in :ref:`namespaces_python_modules`.
+
+ """
if not callable(callable_):
raise exceptions.RuntimeException(