diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-11-25 11:52:40 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2012-11-25 11:52:40 -0500 |
| commit | d8d297e9a14323d923097290c37e8cc240e2ea94 (patch) | |
| tree | 31f41ec69f0effab45ea0fef691cf12dd68a86ed | |
| parent | 32fba82f1953bd5f26b5e1e2e9ac9ff7ff4758fc (diff) | |
| download | external_python_mako-d8d297e9a14323d923097290c37e8cc240e2ea94.tar.gz external_python_mako-d8d297e9a14323d923097290c37e8cc240e2ea94.tar.bz2 external_python_mako-d8d297e9a14323d923097290c37e8cc240e2ea94.zip | |
- add static dependencies example
| -rw-r--r-- | doc/build/inheritance.rst | 8 | ||||
| -rw-r--r-- | doc/build/namespaces.rst | 130 | ||||
| -rw-r--r-- | mako/runtime.py | 9 |
3 files changed, 142 insertions, 5 deletions
diff --git a/doc/build/inheritance.rst b/doc/build/inheritance.rst index b4871bf..9eba053 100644 --- a/doc/build/inheritance.rst +++ b/doc/build/inheritance.rst @@ -73,7 +73,7 @@ Here is a breakdown of the execution: function on all template-based namespaces refers to the main body of the template, therefore the main body of ``index.html`` is rendered. -#. When ``<%block name="header">`` is encountered in ``index.html`` +#. When ``<%block name="header">`` is encountered in ``index.html`` during the ``self.body()`` call, a conditional is checked -- does the current inherited template, i.e. ``base.html``, also define this block? If yes, the ``<%block>`` is **not** executed here -- the inheritance @@ -494,6 +494,8 @@ thing is now: and you're now a template inheritance ninja! +.. _inheritance_attr: + Inheritable Attributes ====================== @@ -532,3 +534,7 @@ you'll get output like: This is the body </div> +.. seealso:: + + :ref:`namespace_attr_for_includes` - a more sophisticated example using + :attr:`.Namespace.attr`. diff --git a/doc/build/namespaces.rst b/doc/build/namespaces.rst index 95e8f7a..078b15a 100644 --- a/doc/build/namespaces.rst +++ b/doc/build/namespaces.rst @@ -130,7 +130,7 @@ 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 +``context``, an instance of :class:`.Context`. A module file ``some/module.py`` might contain the callable: .. sourcecode:: python @@ -328,6 +328,132 @@ 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. +Namespace API Usage Example - Static Dependencies +================================================== + +The ``<%namespace>`` tag at runtime produces an instance of +:class:`.Namespace`. Programmatic access of :class:`.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 :class:`.Namespace` as the +object that holds together the various templates present, we can build a variety +of such schemes. In particular, the :class:`.Context` has a ``namespaces`` +attribute, which is a dictionary of all :class:`.Namespace` objects declared. +Iterating the values of this dictionary will provide a :class:`.Namespace` +object for each time the ``<%namespace>`` tag was used, anywhere within the +inheritance chain. + + +.. _namespace_attr_for_includes: + +Version One - Use :attr:`.Namespace.attr` +----------------------------------------- + +The :attr:`.Namespace.attr` attribute allows us to locate any variables declared +in the ``<%! %>`` of a template. + +.. sourcecode:: mako + + ## 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 reponsible for layout, then locates this attribute and iterates through its contents to produce the includes that are specific to ``library.mako``. + +Version Two - Use a specific named def +----------------------------------------- + +In this version, we put the includes into a ``<%def>`` that +follows a naming convention. + +.. sourcecode:: mako + + ## 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. + API Reference ============= @@ -342,7 +468,7 @@ API Reference .. autoclass:: mako.runtime.ModuleNamespace :show-inheritance: :members: - + .. autofunction:: mako.runtime.supports_caller .. autofunction:: mako.runtime.capture diff --git a/mako/runtime.py b/mako/runtime.py index b5fa944..c483617 100644 --- a/mako/runtime.py +++ b/mako/runtime.py @@ -406,8 +406,13 @@ class Namespace(object): This accessor allows templates to supply "scalar" attributes which are particularly handy in inheritance - relationships. See the example in - :ref:`inheritance_toplevel`. + relationships. + + .. seealso:: + + :ref:`inheritance_attr` + + :ref:`namespace_attr_for_includes` """ return _NSAttr(self) |
