1.. _runtime_toplevel: 2 3============================ 4The Mako Runtime Environment 5============================ 6 7This section describes a little bit about the objects and 8built-in functions that are available in templates. 9 10.. _context: 11 12Context 13======= 14 15The :class:`.Context` is the central object that is created when 16a template is first executed, and is responsible for handling 17all communication with the outside world. Within the template 18environment, it is available via the :ref:`reserved name <reserved_names>` 19``context``. The :class:`.Context` includes two 20major components, one of which is the output buffer, which is a 21file-like object such as Python's ``StringIO`` or similar, and 22the other a dictionary of variables that can be freely 23referenced within a template; this dictionary is a combination 24of the arguments sent to the :meth:`~.Template.render` function and 25some built-in variables provided by Mako's runtime environment. 26 27The Buffer 28---------- 29 30The buffer is stored within the :class:`.Context`, and writing 31to it is achieved by calling the :meth:`~.Context.write` method 32-- in a template this looks like ``context.write('some string')``. 33You usually don't need to care about this, as all text within a template, as 34well as all expressions provided by ``${}``, automatically send 35everything to this method. The cases you might want to be aware 36of its existence are if you are dealing with various 37filtering/buffering scenarios, which are described in 38:ref:`filtering_toplevel`, or if you want to programmatically 39send content to the output stream, such as within a ``<% %>`` 40block. 41 42.. sourcecode:: mako 43 44 <% 45 context.write("some programmatic text") 46 %> 47 48The actual buffer may or may not be the original buffer sent to 49the :class:`.Context` object, as various filtering/caching 50scenarios may "push" a new buffer onto the context's underlying 51buffer stack. For this reason, just stick with 52``context.write()`` and content will always go to the topmost 53buffer. 54 55.. _context_vars: 56 57Context Variables 58----------------- 59 60When your template is compiled into a Python module, the body 61content is enclosed within a Python function called 62``render_body``. Other top-level defs defined in the template are 63defined within their own function bodies which are named after 64the def's name with the prefix ``render_`` (i.e. ``render_mydef``). 65One of the first things that happens within these functions is 66that all variable names that are referenced within the function 67which are not defined in some other way (i.e. such as via 68assignment, module level imports, etc.) are pulled from the 69:class:`.Context` object's dictionary of variables. This is how you're 70able to freely reference variable names in a template which 71automatically correspond to what was passed into the current 72:class:`.Context`. 73 74* **What happens if I reference a variable name that is not in 75 the current context?** - The value you get back is a special 76 value called ``UNDEFINED``, or if the ``strict_undefined=True`` flag 77 is used a ``NameError`` is raised. ``UNDEFINED`` is just a simple global 78 variable with the class :class:`mako.runtime.Undefined`. The 79 ``UNDEFINED`` object throws an error when you call ``str()`` on 80 it, which is what happens if you try to use it in an 81 expression. 82* **UNDEFINED makes it hard for me to find what name is missing** - An alternative 83 is to specify the option ``strict_undefined=True`` 84 to the :class:`.Template` or :class:`.TemplateLookup`. This will cause 85 any non-present variables to raise an immediate ``NameError`` 86 which includes the name of the variable in its message 87 when :meth:`~.Template.render` is called -- ``UNDEFINED`` is not used. 88 89 .. versionadded:: 0.3.6 90 91* **Why not just return None?** Using ``UNDEFINED``, or 92 raising a ``NameError`` is more 93 explicit and allows differentiation between a value of ``None`` 94 that was explicitly passed to the :class:`.Context` and a value that 95 wasn't present at all. 96* **Why raise an exception when you call str() on it ? Why not 97 just return a blank string?** - Mako tries to stick to the 98 Python philosophy of "explicit is better than implicit". In 99 this case, it's decided that the template author should be made 100 to specifically handle a missing value rather than 101 experiencing what may be a silent failure. Since ``UNDEFINED`` 102 is a singleton object just like Python's ``True`` or ``False``, 103 you can use the ``is`` operator to check for it: 104 105 .. sourcecode:: mako 106 107 % if someval is UNDEFINED: 108 someval is: no value 109 % else: 110 someval is: ${someval} 111 % endif 112 113Another facet of the :class:`.Context` is that its dictionary of 114variables is **immutable**. Whatever is set when 115:meth:`~.Template.render` is called is what stays. Of course, since 116its Python, you can hack around this and change values in the 117context's internal dictionary, but this will probably will not 118work as well as you'd think. The reason for this is that Mako in 119many cases creates copies of the :class:`.Context` object, which 120get sent to various elements of the template and inheriting 121templates used in an execution. So changing the value in your 122local :class:`.Context` will not necessarily make that value 123available in other parts of the template's execution. Examples 124of where Mako creates copies of the :class:`.Context` include 125within top-level def calls from the main body of the template 126(the context is used to propagate locally assigned variables 127into the scope of defs; since in the template's body they appear 128as inlined functions, Mako tries to make them act that way), and 129within an inheritance chain (each template in an inheritance 130chain has a different notion of ``parent`` and ``next``, which 131are all stored in unique :class:`.Context` instances). 132 133* **So what if I want to set values that are global to everyone 134 within a template request?** - All you have to do is provide a 135 dictionary to your :class:`.Context` when the template first 136 runs, and everyone can just get/set variables from that. Lets 137 say its called ``attributes``. 138 139 Running the template looks like: 140 141 .. sourcecode:: python 142 143 output = template.render(attributes={}) 144 145 Within a template, just reference the dictionary: 146 147 .. sourcecode:: mako 148 149 <% 150 attributes['foo'] = 'bar' 151 %> 152 'foo' attribute is: ${attributes['foo']} 153 154* **Why can't "attributes" be a built-in feature of the 155 Context?** - This is an area where Mako is trying to make as 156 few decisions about your application as it possibly can. 157 Perhaps you don't want your templates to use this technique of 158 assigning and sharing data, or perhaps you have a different 159 notion of the names and kinds of data structures that should 160 be passed around. Once again Mako would rather ask the user to 161 be explicit. 162 163Context Methods and Accessors 164----------------------------- 165 166Significant members of :class:`.Context` include: 167 168* ``context[key]`` / ``context.get(key, default=None)`` - 169 dictionary-like accessors for the context. Normally, any 170 variable you use in your template is automatically pulled from 171 the context if it isn't defined somewhere already. Use the 172 dictionary accessor and/or ``get`` method when you want a 173 variable that *is* already defined somewhere else, such as in 174 the local arguments sent to a ``%def`` call. If a key is not 175 present, like a dictionary it raises ``KeyError``. 176* ``keys()`` - all the names defined within this context. 177* ``kwargs`` - this returns a **copy** of the context's 178 dictionary of variables. This is useful when you want to 179 propagate the variables in the current context to a function 180 as keyword arguments, i.e.: 181 182 .. sourcecode:: mako 183 184 ${next.body(**context.kwargs)} 185 186* ``write(text)`` - write some text to the current output 187 stream. 188* ``lookup`` - returns the :class:`.TemplateLookup` instance that is 189 used for all file-lookups within the current execution (even 190 though individual :class:`.Template` instances can conceivably have 191 different instances of a :class:`.TemplateLookup`, only the 192 :class:`.TemplateLookup` of the originally-called :class:`.Template` gets 193 used in a particular execution). 194 195.. _loop_context: 196 197The Loop Context 198================ 199 200Within ``% for`` blocks, the :ref:`reserved name<reserved_names>` ``loop`` 201is available. ``loop`` tracks the progress of 202the ``for`` loop and makes it easy to use the iteration state to control 203template behavior: 204 205.. sourcecode:: mako 206 207 <ul> 208 % for a in ("one", "two", "three"): 209 <li>Item ${loop.index}: ${a}</li> 210 % endfor 211 </ul> 212 213.. versionadded:: 0.7 214 215Iterations 216---------- 217 218Regardless of the type of iterable you're looping over, ``loop`` always tracks 219the 0-indexed iteration count (available at ``loop.index``), its parity 220(through the ``loop.even`` and ``loop.odd`` bools), and ``loop.first``, a bool 221indicating whether the loop is on its first iteration. If your iterable 222provides a ``__len__`` method, ``loop`` also provides access to 223a count of iterations remaining at ``loop.reverse_index`` and ``loop.last``, 224a bool indicating whether the loop is on its last iteration; accessing these 225without ``__len__`` will raise a ``TypeError``. 226 227Cycling 228------- 229 230Cycling is available regardless of whether the iterable you're using provides 231a ``__len__`` method. Prior to Mako 0.7, you might have generated a simple 232zebra striped list using ``enumerate``: 233 234.. sourcecode:: mako 235 236 <ul> 237 % for i, item in enumerate(('spam', 'ham', 'eggs')): 238 <li class="${'odd' if i % 2 else 'even'}">${item}</li> 239 % endfor 240 </ul> 241 242With ``loop.cycle``, you get the same results with cleaner code and less prep work: 243 244.. sourcecode:: mako 245 246 <ul> 247 % for item in ('spam', 'ham', 'eggs'): 248 <li class="${loop.cycle('even', 'odd')}">${item}</li> 249 % endfor 250 </ul> 251 252Both approaches produce output like the following: 253 254.. sourcecode:: html 255 256 <ul> 257 <li class="even">spam</li> 258 <li class="odd">ham</li> 259 <li class="even">eggs</li> 260 </ul> 261 262Parent Loops 263------------ 264 265Loop contexts can also be transparently nested, and the Mako runtime will do 266the right thing and manage the scope for you. You can access the parent loop 267context through ``loop.parent``. 268 269This allows you to reach all the way back up through the loop stack by 270chaining ``parent`` attribute accesses, i.e. ``loop.parent.parent....`` as 271long as the stack depth isn't exceeded. For example, you can use the parent 272loop to make a checkered table: 273 274.. sourcecode:: mako 275 276 <table> 277 % for consonant in 'pbj': 278 <tr> 279 % for vowel in 'iou': 280 <td class="${'black' if (loop.parent.even == loop.even) else 'red'}"> 281 ${consonant + vowel}t 282 </td> 283 % endfor 284 </tr> 285 % endfor 286 </table> 287 288.. sourcecode:: html 289 290 <table> 291 <tr> 292 <td class="black"> 293 pit 294 </td> 295 <td class="red"> 296 pot 297 </td> 298 <td class="black"> 299 put 300 </td> 301 </tr> 302 <tr> 303 <td class="red"> 304 bit 305 </td> 306 <td class="black"> 307 bot 308 </td> 309 <td class="red"> 310 but 311 </td> 312 </tr> 313 <tr> 314 <td class="black"> 315 jit 316 </td> 317 <td class="red"> 318 jot 319 </td> 320 <td class="black"> 321 jut 322 </td> 323 </tr> 324 </table> 325 326.. _migrating_loop: 327 328Migrating Legacy Templates that Use the Word "loop" 329--------------------------------------------------- 330 331.. versionchanged:: 0.7 332 The ``loop`` name is now :ref:`reserved <reserved_names>` in Mako, 333 which means a template that refers to a variable named ``loop`` 334 won't function correctly when used in Mako 0.7. 335 336To ease the transition for such systems, the feature can be disabled across the board for 337all templates, then re-enabled on a per-template basis for those templates which wish 338to make use of the new system. 339 340First, the ``enable_loop=False`` flag is passed to either the :class:`.TemplateLookup` 341or :class:`.Template` object in use: 342 343.. sourcecode:: python 344 345 lookup = TemplateLookup(directories=['/docs'], enable_loop=False) 346 347or: 348 349.. sourcecode:: python 350 351 template = Template("some template", enable_loop=False) 352 353An individual template can make usage of the feature when ``enable_loop`` is set to 354``False`` by switching it back on within the ``<%page>`` tag: 355 356.. sourcecode:: mako 357 358 <%page enable_loop="True"/> 359 360 % for i in collection: 361 ${i} ${loop.index} 362 % endfor 363 364Using the above scheme, it's safe to pass the name ``loop`` to the :meth:`.Template.render` 365method as well as to freely make usage of a variable named ``loop`` within a template, provided 366the ``<%page>`` tag doesn't override it. New templates that want to use the ``loop`` context 367can then set up ``<%page enable_loop="True"/>`` to use the new feature without affecting 368old templates. 369 370All the Built-in Names 371====================== 372 373A one-stop shop for all the names Mako defines. Most of these 374names are instances of :class:`.Namespace`, which are described 375in the next section, :ref:`namespaces_toplevel`. Also, most of 376these names other than ``context``, ``UNDEFINED``, and ``loop`` are 377also present *within* the :class:`.Context` itself. The names 378``context``, ``loop`` and ``UNDEFINED`` themselves can't be passed 379to the context and can't be substituted -- see the section :ref:`reserved_names`. 380 381* ``context`` - this is the :class:`.Context` object, introduced 382 at :ref:`context`. 383* ``local`` - the namespace of the current template, described 384 in :ref:`namespaces_builtin`. 385* ``self`` - the namespace of the topmost template in an 386 inheritance chain (if any, otherwise the same as ``local``), 387 mostly described in :ref:`inheritance_toplevel`. 388* ``parent`` - the namespace of the parent template in an 389 inheritance chain (otherwise undefined); see 390 :ref:`inheritance_toplevel`. 391* ``next`` - the namespace of the next template in an 392 inheritance chain (otherwise undefined); see 393 :ref:`inheritance_toplevel`. 394* ``caller`` - a "mini" namespace created when using the 395 ``<%call>`` tag to define a "def call with content"; described 396 in :ref:`defs_with_content`. 397* ``loop`` - this provides access to :class:`.LoopContext` objects when 398 they are requested within ``% for`` loops, introduced at :ref:`loop_context`. 399* ``capture`` - a function that calls a given def and captures 400 its resulting content into a string, which is returned. Usage 401 is described in :ref:`filtering_toplevel`. 402* ``UNDEFINED`` - a global singleton that is applied to all 403 otherwise uninitialized template variables that were not 404 located within the :class:`.Context` when rendering began, 405 unless the :class:`.Template` flag ``strict_undefined`` 406 is set to ``True``. ``UNDEFINED`` is 407 an instance of :class:`.Undefined`, and raises an 408 exception when its ``__str__()`` method is called. 409* ``pageargs`` - this is a dictionary which is present in a 410 template which does not define any ``**kwargs`` section in its 411 ``<%page>`` tag. All keyword arguments sent to the ``body()`` 412 function of a template (when used via namespaces) go here by 413 default unless otherwise defined as a page argument. If this 414 makes no sense, it shouldn't; read the section 415 :ref:`namespaces_body`. 416 417.. _reserved_names: 418 419Reserved Names 420-------------- 421 422Mako has a few names that are considered to be "reserved" and can't be used 423as variable names. 424 425.. versionchanged:: 0.7 426 Mako raises an error if these words are found passed to the template 427 as context arguments, whereas in previous versions they'd be silently 428 ignored or lead to other error messages. 429 430* ``context`` - see :ref:`context`. 431* ``UNDEFINED`` - see :ref:`context_vars`. 432* ``loop`` - see :ref:`loop_context`. Note this can be disabled for legacy templates 433 via the ``enable_loop=False`` argument; see :ref:`migrating_loop`. 434 435API Reference 436============= 437 438.. autoclass:: mako.runtime.Context 439 :show-inheritance: 440 :members: 441 442.. autoclass:: mako.runtime.LoopContext 443 :show-inheritance: 444 :members: 445 446.. autoclass:: mako.runtime.Undefined 447 :show-inheritance: 448 449