summaryrefslogtreecommitdiff
path: root/doc/build/syntax.rst
blob: 28735841691c1724d6dc224462ee8b12e1dab1c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
.. _syntax_toplevel:

======
Syntax
======

A Mako template is parsed from a text stream containing any kind
of content, XML, HTML, email text, etc. The template can further
contain Mako-specific directives which represent variable and/or
expression substitutions, control structures (i.e. conditionals
and loops), server-side comments, full blocks of Python code, as
well as various tags that offer additional functionality. All of
these constructs compile into real Python code. This means that
you can leverage the full power of Python in almost every aspect
of a Mako template.

Expression Substitution
=======================

The simplest expression is just a variable substitution. The
syntax for this is the ``${}`` construct, which is inspired by
Perl, Genshi, JSP EL, and others:

.. sourcecode:: mako

    this is x: ${x}

Above, the string representation of ``x`` is applied to the
template's output stream. If you're wondering where ``x`` comes
from, it's usually from the :class:`.Context` supplied to the
template's rendering function. If ``x`` was not supplied to the
template and was not otherwise assigned locally, it evaluates to
a special value ``UNDEFINED``. More on that later.

The contents within the ``${}`` tag are evaluated by Python
directly, so full expressions are OK:

.. sourcecode:: mako

    pythagorean theorem:  ${pow(x,2) + pow(y,2)}

The results of the expression are evaluated into a string result
in all cases before being rendered to the output stream, such as
the above example where the expression produces a numeric
result.

Expression Escaping
===================

Mako includes a number of built-in escaping mechanisms,
including HTML, URI and XML escaping, as well as a "trim"
function. These escapes can be added to an expression
substitution using the ``|`` operator:

.. sourcecode:: mako

    ${"this is some text" | u}

The above expression applies URL escaping to the expression, and
produces ``this+is+some+text``. The ``u`` name indicates URL
escaping, whereas ``h`` represents HTML escaping, ``x``
represents XML escaping, and ``trim`` applies a trim function.

Read more about built-in filtering functions, including how to
make your own filter functions, in :ref:`filtering_toplevel`.

Control Structures
==================

A control structure refers to all those things that control the
flow of a program -- conditionals (i.e. ``if``/``else``), loops (like
``while`` and ``for``), as well as things like ``try``/``except``. In Mako,
control structures are written using the ``%`` marker followed
by a regular Python control expression, and are "closed" by
using another ``%`` marker with the tag "``end<name>``", where
"``<name>``" is the keyword of the expression:

.. sourcecode:: mako

    % if x==5:
        this is some output
    % endif

The ``%`` can appear anywhere on the line as long as no text
precedes it; indentation is not significant. The full range of
Python "colon" expressions are allowed here, including
``if``/``elif``/``else``, ``while``, ``for``, ``with``, and even ``def``,
although Mako has a built-in tag for defs which is more full-featured.

.. sourcecode:: mako

    % for a in ['one', 'two', 'three', 'four', 'five']:
        % if a[0] == 't':
        its two or three
        % elif a[0] == 'f':
        four/five
        % else:
        one
        % endif
    % endfor

The ``%`` sign can also be "escaped", if you actually want to
emit a percent sign as the first non whitespace character on a
line, by escaping it as in ``%%``:

.. sourcecode:: mako

    %% some text

        %% some more text

The Loop Context
----------------

The **loop context** provides additional information about a loop
while inside of a ``% for`` structure:

.. sourcecode:: mako

    <ul>
    % for a in ("one", "two", "three"):
        <li>Item ${loop.index}: ${a}</li>
    % endfor
    </ul>

See :ref:`loop_context` for more information on this feature.

.. versionadded:: 0.7

Comments
========

Comments come in two varieties. The single line comment uses
``##`` as the first non-space characters on a line:

.. sourcecode:: mako

    ## this is a comment.
    ...text ...

A multiline version exists using ``<%doc> ...text... </%doc>``:

.. sourcecode:: mako

    <%doc>
        these are comments
        more comments
    </%doc>

Newline Filters
===============

The backslash ("``\``") character, placed at the end of any
line, will consume the newline character before continuing to
the next line:

.. sourcecode:: mako

    here is a line that goes onto \
    another line.

The above text evaluates to:

.. sourcecode:: text

    here is a line that goes onto another line.

Python Blocks
=============

Any arbitrary block of python can be dropped in using the ``<%
%>`` tags:

.. sourcecode:: mako

    this is a template
    <%
        x = db.get_resource('foo')
        y = [z.element for z in x if x.frobnizzle==5]
    %>
    % for elem in y:
        element: ${elem}
    % endfor

Within ``<% %>``, you're writing a regular block of Python code.
While the code can appear with an arbitrary level of preceding
whitespace, it has to be consistently formatted with itself.
Mako's compiler will adjust the block of Python to be consistent
with the surrounding generated Python code.

Module-level Blocks
===================

A variant on ``<% %>`` is the module-level code block, denoted
by ``<%! %>``. Code within these tags is executed at the module
level of the template, and not within the rendering function of
the template. Therefore, this code does not have access to the
template's context and is only executed when the template is
loaded into memory (which can be only once per application, or
more, depending on the runtime environment). Use the ``<%! %>``
tags to declare your template's imports, as well as any
pure-Python functions you might want to declare:

.. sourcecode:: mako

    <%!
        import mylib
        import re

        def filter(text):
            return re.sub(r'^@', '', text)
    %>

Any number of ``<%! %>`` blocks can be declared anywhere in a
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
====

The rest of what Mako offers takes place in the form of tags.
All tags use the same syntax, which is similar to an XML tag
except that the first character of the tag name is a ``%``
character. The tag is closed either by a contained slash
character, or an explicit closing tag:

.. sourcecode:: mako

    <%include file="foo.txt"/>

    <%def name="foo" buffered="True">
        this is a def
    </%def>

All tags have a set of attributes which are defined for each
tag. Some of these attributes are required. Also, many
attributes support **evaluation**, meaning you can embed an
expression (using ``${}``) inside the attribute text:

.. sourcecode:: mako

    <%include file="/foo/bar/${myfile}.txt"/>

Whether or not an attribute accepts runtime evaluation depends
on the type of tag and how that tag is compiled into the
template. The best way to find out if you can stick an
expression in is to try it! The lexer will tell you if it's not
valid.

Heres a quick summary of all the tags:

``<%page>``
-----------

This tag defines general characteristics of the template,
including caching arguments, and optional lists of arguments
which the template expects when invoked.

.. sourcecode:: mako

    <%page args="x, y, z='default'"/>

Or a page tag that defines caching characteristics:

.. sourcecode:: mako

    <%page cached="True" cache_type="memory"/>

Currently, only one ``<%page>`` tag gets used per template, the
rest get ignored. While this will be improved in a future
release, for now make sure you have only one ``<%page>`` tag
defined in your template, else you may not get the results you
want.  Further details on what ``<%page>`` is used for are described
in the following sections:

* :ref:`namespaces_body` - ``<%page>`` is used to define template-level
  arguments and defaults

* :ref:`expression_filtering` - expression filters can be applied to all
  expressions throughout a template using the ``<%page>`` tag

* :ref:`caching_toplevel` - options to control template-level caching
  may be applied in the ``<%page>`` tag.

``<%include>``
--------------

A tag that is familiar from other template languages, ``%include``
is a regular joe that just accepts a file argument and calls in
the rendered result of that file:

.. sourcecode:: mako

    <%include file="header.html"/>

        hello world

    <%include file="footer.html"/>

Include also accepts arguments which are available as ``<%page>`` arguments in the receiving template:

.. sourcecode:: mako

    <%include file="toolbar.html" args="current_section='members', username='ed'"/>

``<%def>``
----------

The ``%def`` tag defines a Python function which contains a set
of content, that can be called at some other point in the
template. The basic idea is simple:

.. sourcecode:: mako

    <%def name="myfunc(x)">
        this is myfunc, x is ${x}
    </%def>

    ${myfunc(7)}

The ``%def`` tag is a lot more powerful than a plain Python ``def``, as
the Mako compiler provides many extra services with ``%def`` that
you wouldn't normally have, such as the ability to export defs
as template "methods", automatic propagation of the current
:class:`.Context`, buffering/filtering/caching flags, and def calls
with content, which enable packages of defs to be sent as
arguments to other def calls (not as hard as it sounds). Get the
full deal on what ``%def`` can do in :ref:`defs_toplevel`.

``<%block>``
------------

``%block`` is a tag that is close to a ``%def``,
except executes itself immediately in its base-most scope,
and can also be anonymous (i.e. with no name):

.. sourcecode:: mako

    <%block filter="h">
        some <html> stuff.
    </%block>

Inspired by Jinja2 blocks, named blocks offer a syntactically pleasing way
to do inheritance:

.. sourcecode:: mako

    <html>
        <body>
        <%block name="header">
            <h2><%block name="title"/></h2>
        </%block>
        ${self.body()}
        </body>
    </html>

Blocks are introduced in :ref:`blocks` and further described in :ref:`inheritance_toplevel`.

.. versionadded:: 0.4.1

``<%namespace>``
----------------

``%namespace`` is Mako's equivalent of Python's ``import``
statement. It allows access to all the rendering functions and
metadata of other template files, plain Python modules, as well
as locally defined "packages" of functions.

.. sourcecode:: mako

    <%namespace file="functions.html" import="*"/>

The underlying object generated by ``%namespace``, an instance of
:class:`.mako.runtime.Namespace`, is a central construct used in
templates to reference template-specific information such as the
current URI, inheritance structures, and other things that are
not as hard as they sound right here. Namespaces are described
in :ref:`namespaces_toplevel`.

``<%inherit>``
--------------

Inherit allows templates to arrange themselves in **inheritance
chains**. This is a concept familiar in many other template
languages.

.. sourcecode:: mako

    <%inherit file="base.html"/>

When using the ``%inherit`` tag, control is passed to the topmost
inherited template first, which then decides how to handle
calling areas of content from its inheriting templates. Mako
offers a lot of flexibility in this area, including dynamic
inheritance, content wrapping, and polymorphic method calls.
Check it out in :ref:`inheritance_toplevel`.

``<%``\ nsname\ ``:``\ defname\ ``>``
-------------------------------------

Any user-defined "tag" can be created against
a namespace by using a tag with a name of the form
``<%<namespacename>:<defname>>``. The closed and open formats of such a
tag are equivalent to an inline expression and the ``<%call>``
tag, respectively.

.. sourcecode:: mako

    <%mynamespace:somedef param="some value">
        this is the body
    </%mynamespace:somedef>

To create custom tags which accept a body, see
:ref:`defs_with_content`.

.. versionadded:: 0.2.3

``<%call>``
-----------

The call tag is the "classic" form of a user-defined tag, and is
roughly equivalent to the ``<%namespacename:defname>`` syntax
described above. This tag is also described in :ref:`defs_with_content`.

``<%doc>``
----------

The ``%doc`` tag handles multiline comments:

.. sourcecode:: mako

    <%doc>
        these are comments
        more comments
    </%doc>

Also the ``##`` symbol as the first non-space characters on a line can be used for single line comments.

``<%text>``
-----------

This tag suspends the Mako lexer's normal parsing of Mako
template directives, and returns its entire body contents as
plain text. It is used pretty much to write documentation about
Mako:

.. sourcecode:: mako

    <%text filter="h">
        heres some fake mako ${syntax}
        <%def name="x()">${x}</%def>
    </%text>

.. _syntax_exiting_early:

Exiting Early from a Template
=============================

Sometimes you want to stop processing a template or ``<%def>``
method in the middle and just use the text you've accumulated so
far.  This is accomplished by using ``return`` statement inside
a Python block.   It's a good idea for the ``return`` statement
to return an empty string, which prevents the Python default return
value of ``None`` from being rendered by the template.  This
return value is for semantic purposes provided in templates via
the ``STOP_RENDERING`` symbol:

.. sourcecode:: mako

    % if not len(records):
        No records found.
        <% return STOP_RENDERING %>
    % endif

Or perhaps:

.. sourcecode:: mako

    <%
        if not len(records):
            return STOP_RENDERING
    %>

In older versions of Mako, an empty string can be substituted for
the ``STOP_RENDERING`` symbol:

.. sourcecode:: mako

    <% return '' %>

.. versionadded:: 1.0.2 - added the ``STOP_RENDERING`` symbol which serves
   as a semantic identifier for the empty string ``""`` used by a
   Python ``return`` statement.