Tags
####
The template code tries to mimic Python syntax as far as possible, but is
limited to what is required for templates and does not allow executing arbitrary
Python statements. In some spots it also borrows Javascript semantics.
:mod:`ll.ul4c` supports the following tag types:
````
=============
The ``print`` tag outputs the value of a variable or any other expression. If
the expression doesn't evaluate to a string it will be converted to a string
first. The format of the string depends on the renderer, but should follow
Python's ``str()`` output as much as possible:
.. sourcecode:: html+ul4
,
Printing ``None`` or undefined objects produces no output.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.PrintAST`.
````
==============
The ``printx`` tag outputs the value of a variable or any other expression and
escapes the characters ``<``, ``>``, ``&``, ``'`` and ``"`` with the appropriate
character or entity references for XML or HTML output.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.PrintXAST`.
````
===========
The ``for`` tag can be used to loop over the items in a list, the characters in
a string, the keys in a dictionary or any other iterable object. The end of the
loop body must be marked with an ```` tag:
.. sourcecode:: html+ul4
In ``for`` loops variable unpacking is supported, so you can do the following:
.. sourcecode:: ul4
if ``dict`` is a dictionary.
This unpacking can be arbitrarily nested, i.e. the following is possible too:
.. sourcecode:: ul4
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.ForBlockAST`.
````
=============
The ``break`` tag can be used to break out of the innermost running loop.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.BreakAST`.
````
================
The ``continue`` tag can be used to skip the rest of the loop body of the
innermost running loop and continue with the next iteration of the loop.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.ContinueAST`.
````
==========
The ``if`` tag can be used to output a part of the template only when a
condition is true. The end of the ``if`` block must be marked with an
```` tag. The truth value of an object is mostly the same as in Python:
* ``None`` is false.
* The integer ``0`` and the float value ``0.0`` are false.
* Empty strings, lists and dictionaries are false.
* ``timedelta`` and ``monthdelta`` objects for an empty timespan (i.e.
``timedelta(0, 0, 0)`` and ``monthdelta(0)``) are false.
* ``False`` is false.
* ``Undefined`` is false.
* Anything else is true.
For example we can output the person list only if there are any persons:
.. sourcecode:: html+ul4
``elif`` and ``else`` are supported too:
.. sourcecode:: html+ul4
No persons found!
or:
.. sourcecode:: html+ul4
No persons found!
One person found!
persons found!
.. hint::
The ````, ```` and ```` tags are implemented by
:class:`ll.ul4c.ConditionalBlocksAST`, :class:`ll.ul4c.IfBlockAST`,
:class:`ll.ul4c.ElIfBlockAST` and :class:`ll.ul4c.ElseBlockAST`.
````
============
The ``code`` tag can contain statements that define or modify variables or
expressions which will be evaluated for their side effects. Apart from the
assigment operator ``=``, the following augmented assignment operators are
supported:
* ``+=`` (adds a value to the variable)
* ``-=`` (subtracts a value from the variable)
* ``*=`` (multiplies the variable by a value)
* ``/=`` (divides the variable by a value)
* ``//=`` (divides the variable by a value, rounding down to the next
smallest integer)
* ``%=`` (Does a modulo operation and replaces the variable value with the
result)
* ``<<=`` (Does bitwise "shift left" operation and replaces the variable value
with the result)
* ``>>=`` (Does bitwise "shift right" operation and replaces the variable value
with the result)
* ``&=`` (Does bitwise "and" operation and replaces the variable value with
the result)
* ``|=`` (Does bitwise "or" operation and replaces the variable value with
the result)
* ``^=`` (Does bitwise "exclusive-or" operation and replaces the variable
value with the result)
For example the following template will output ``40``:
.. sourcecode:: ul4
.. hint::
The content of ```` tags is implemented as
:ref:`UL4 expressions `.
````
==============
The ``render`` tag allows one template to call other templates. The following
Python code demonstrates this:
.. sourcecode:: python
from ll import ul4c
# Template 1
source1 = """\
\
\
"""
tmpl1 = ul4c.Template(source1)
# Template 2
source2 = "\n"
tmpl2 = ul4c.Template(source2)
# Data object for the outer template
data = ["Python", "Java", "Javascript", "PHP"]
print(tmpl1.renders(itemtmpl=tmpl2, data=data))
This will output:
.. sourcecode:: html
- Python
- Java
- Javascript
- PHP
I.e. templates can be passed just like any other object as a variable.
```` renders the ``itemtmpl`` template and passes
the ``i`` variable, which will be available in the inner template under the
name ``item``.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.RenderAST`.
````
===============
The ``renderx`` tag works similar to the ``render`` tag, except that the output
of the template called will be XML escaped (like ``printx`` does). The following
Python code demonstrates this:
.. sourcecode:: python
from ll import ul4c
# Template 1
tmpl1 = ul4c.Template("<&>")
# Template 2
tmpl2 = ul4c.Template("\n")
print(tmpl1.renders(tmpl=tmpl2))
This will output:
.. sourcecode:: html
<&>
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.RenderXAST`.
````
===========
The ``def`` tag defines a new template as a variable. Usage looks like this:
.. sourcecode:: ul4
""
This defines a local variable ``quote`` that is a template object. This template
can be rendered like any other template that has been passed to the outermost
template:
.. sourcecode:: ul4
It's also possible to include a signature in the definition of the template.
This makes it possible to define default values for template variables and to
call templates with positional arguments:
.. sourcecode:: ul4
""
and
This will output ``"foo" and "bar"``.
``*`` and ``**`` arguments are also supported:
.. sourcecode:: ul4
This will print ``189`` (i.e. ``1 * 17 + 2 * 23 + 3 * 42``).
.. hint::
The ```` tag simply creates a :class:`~ll.ul4c.Template` object inside
another :class:`~ll.ul4c.Template` object.
````
====================
The ``renderblocks`` tag is syntactic sugar for rendering a template and
passing other templates as arguments in the call. For example if we have the
following template:
.. sourcecode:: html+ul4
then we can render this template in the following way:
.. sourcecode:: html+ul4
Foo
Bar!
This is syntactic sugar for:
.. sourcecode:: html+ul4
Foo
Bar!
In both cases the output will be:
.. sourcecode:: html
Foo
Bar!
All variables defined between ```` and
```` are passed as additional keyword arguments in the
render call to ``page``. (But note that those variables will be local to the
```` block, i.e. they will not leak into the surrounding
code.)
.. hint::
The ```` tag is implemented by
:class:`ll.ul4c.RenderBlocksAST`.
````
===================
The ``renderblock`` is a special version of ``renderblocks``. The complete
content of the ``renderblock`` block will be wrapped in a signatureless template
named ``content`` and this template will be passed as the keyword argument
``content`` to the render call. With this we can define a generic template for
HTML links:
.. sourcecode:: ul4
="">
and then use it like this:
.. sourcecode:: html+ul4
Link to the Python homepage
The output will be:
.. sourcecode:: html
Link to the Python homepage
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.RenderBlockAST`.
````
==============
The ``return`` tag returns a value from the template when the template is
called as a function. For more info see :ref:`UL4_TemplatesAsFunctions`.
.. hint::
The ```` tag is implemented by :class:`ll.ul4c.ReturnAST`.
````
===========
The ``ul4`` tag can be used to specify a name and a signature for the template
itself. This overwrites the name and signature specified in the
:class:`ul4c.Template` constructor:
.. sourcecode:: python
>>> from ll import ul4c
>>> t = ul4c.Template("")
>>> t.name
'foo'
>>> t.signature
.. hint::
The ```` tag has no corresponding AST nodes. Its content will set
attributes of the template instead.
````
============
A ``note`` tag is a comment and can be used to explain the template code.
When the template gets executed, the content of the tag will be completely
ignored.
.. hint::
A ```` tag has no corresponding AST nodes.
````
===========
A ``doc`` tag contains the documentation of the template itself. The content
of the ```` tag is available as the ``doc`` attribute:
.. sourcecode:: python
>>> from ll import ul4c
>>> t = ul4c.Template("")
>>> t.doc
'foo'
Each ```` contains the documentation for the template to which the
```` tag belongs, i.e. if the ```` tag is at the outermost
level, it belongs to the outermost template. If the ```` tag is inside
a local template, it is the documentation for the local template. If multiple
```` tags are given, only the first one will be used, all later ones will
be ignored.
Note that the template name, documentation and signature are accessible inside
the templates themselves, i.e.:
.. sourcecode:: ul4
will output:
.. sourcecode:: output
f
return the sum of x and y
(x=17, y=23)
.. hint::
A ```` tag has no corresponding AST nodes. Its content will set the
``doc`` property of the template instead.
````
==============
An ``ignore`` tag can be used to "comment out" template code, so that the
code will never be executed. ```` and ```` tags nest,
so code that already contains ```` and ```` tags
can be ignored by added additional ```` and ```` tags
around it.
It is not required that the content between the ```` and
```` tag is proper UL4 code.
For example the follow template won't output anything:
.. sourcecode:: ul4
.. hint::
An ```` tag has no corresponding AST nodes.
````
==================
The ``whitespace`` tag can be used to overwrite the handling of whitespace in
the template. For more info see :ref:`UL4_Whitespace`.
.. hint::
A ```` tag has no corresponding AST nodes. Its content will
set the ``whitespace`` attribute of the template instead.