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:: xml+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:: xml+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:: xml+ul4 ``elif`` and ``else`` are supported too: .. sourcecode:: xml+ul4

No persons found!

or: .. sourcecode:: xml+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 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 ``render_or_print`` tag combines the functionality of the ``render`` and the ``print`` tag, so for example .. sourcecode:: ul4 is more or less equivalent to .. sourcecode:: ul4 i.e. if ``foo`` is renderable, it will be rendered, otherwise it will be printed. Furthermore the arguments to the call will always be evaluated even if ``foo`` isn't renderable, so for example: .. sourcecode:: ul4 will fail with:: ~~~~~~~~~ TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType' .. hint:: The ```` tag is implemented by :class:`ll.ul4c.RenderOrPrintAST`. ```` ======================== The ``render_or_printx`` tag is similar to ``render_or_print`` except that the object will be output via ```` instead of ```` if it isn't renderable. .. hint:: The ```` tag is implemented by :class:`ll.ul4c.RenderOrPrintXAST`. ```` ======================== The ``renderx_or_print`` tag is similar to ``render_or_print`` except that the object will be rendered via ```` instead of ```` if it is renderable. .. hint:: The ```` tag is implemented by :class:`ll.ul4c.RenderXOrPrintAST`. ```` ========================= The ``renderx_or_printx`` tag is similar to ``renderx_or_print`` except that the object will be output via ```` instead of ```` if it isn't renderable. .. hint:: The ```` tag is implemented by :class:`ll.ul4c.RenderXOrPrintXAST`. ```` =========== 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:: xml+ul4 then we can render this template in the following way: .. sourcecode:: xml+ul4 Foo

    Bar!

    This is syntactic sugar for: .. sourcecode:: xml+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:: xml+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. The ```` tag supports two variants: * The comment can be included as the content of the tag: .. sourcecode:: ul4 * The comment can be included between a ```` and an ```` tag: .. sourcecode:: ul4 comment This second variant makes it possible to include UL4 source code in ```` tags. .. 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. The ```` tag supports two variants: * The description can be included as the content of the tag: .. sourcecode:: ul4 * The description can be included between a ```` and an ```` tag: .. sourcecode:: ul4 description This second variant makes it possible to include UL4 source code in ```` tags. 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.