summaryrefslogtreecommitdiff
path: root/doc/build/syntax.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/build/syntax.rst')
-rw-r--r--doc/build/syntax.rst495
1 files changed, 495 insertions, 0 deletions
diff --git a/doc/build/syntax.rst b/doc/build/syntax.rst
new file mode 100644
index 0000000..2873584
--- /dev/null
+++ b/doc/build/syntax.rst
@@ -0,0 +1,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.
+