view doc/text-templates.txt @ 510:ca7d707d51b0

Use syntax highlighting on all the other doc pages, too.
author cmlenz
date Wed, 06 Jun 2007 10:41:41 +0000
parents 2abf0a19058b
children 7145e4eba2ec f0bb2c5ea0ff
line wrap: on
line source
.. -*- mode: rst; encoding: utf-8 -*-

=============================
Genshi Text Template Language
=============================

In addition to the XML-based template language, Genshi provides a simple
text-based template language, intended for basic plain text generation needs.
The language is similar to Cheetah_ or Velocity_.

.. _cheetah: http://cheetahtemplate.org/
.. _velocity: http://jakarta.apache.org/velocity/

This document describes the template language and will be most useful as
reference to those developing Genshi text templates. Templates are text files of
some kind that include processing directives_ that affect how the template is
rendered, and template expressions that are dynamically substituted by
variable data.

See `Genshi Templating Basics <templates.html>`_ for general information on
embedding Python code in templates.


.. contents:: Contents
   :depth: 3
.. sectnum::


.. _`directives`:

-------------------
Template Directives
-------------------

Directives are lines starting with a ``#`` character followed immediately by
the directive name. They can affect how the template is rendered in a number of
ways: Genshi provides directives for conditionals and looping, among others.

Directives must be on separate lines, and the ``#`` character must be be the
first non-whitespace character on that line. Each directive must be “closed”
using a ``#end`` marker. You can add after the ``#end`` marker, for example to
document which directive is being closed, or even the expression associated with 
that directive. Any text after ``#end`` (but on the same line) is  ignored, 
and effectively treated as a comment.

If you want to include a literal ``#`` in the output, you need to escape it
by prepending a backslash character (``\``). Note that this is **not** required 
if the ``#`` isn't immediately followed by a letter, or it isn't the first
non-whitespace character on the line.


Conditional Sections
====================

.. _`#if`:

``#if``
---------

The content is only rendered if the expression evaluates to a truth value:

.. code-block:: genshitext

  #if foo
    ${bar}
  #end

Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this
would produce::

    Hello


.. _`#choose`:
.. _`#when`:
.. _`#otherwise`:

``#choose``
-------------

The ``#choose`` directive, in combination with the directives ``#when`` and
``#otherwise`` provides advanced contional processing for rendering one of
several alternatives. The first matching ``#when`` branch is rendered, or, if
no ``#when`` branch matches, the ``#otherwise`` branch is be rendered.

If the ``#choose`` directive has no argument the nested ``#when`` directives
will be tested for truth:

.. code-block:: genshitext

  The answer is:
  #choose
    #when 0 == 1
      0
    #end
    #when 1 == 1
      1
    #end
    #otherwise
      2
    #end
  #end

This would produce the following output::

  The answer is:
      1

If the ``#choose`` does have an argument, the nested ``#when`` directives will
be tested for equality to the parent ``#choose`` value:

.. code-block:: genshitext

  The answer is:
  #choose 1
    #when 0
      0
    #end
    #when 1
      1
    #end
    #otherwise
      2
    #end
  #end

This would produce the following output::

  The answer is:
      1


Looping
=======

.. _`#for`:

``#for``
----------

The content is repeated for every item in an iterable:

.. code-block:: genshitext

  Your items:
  #for item in items
    * ${item}
  #end

Given ``items=[1, 2, 3]`` in the context data, this would produce::

  Your items
    * 1
    * 2
    * 3


Snippet Reuse
=============

.. _`#def`:
.. _`macros`:

``#def``
----------

The ``#def`` directive can be used to create macros, i.e. snippets of template
text that have a name and optionally some parameters, and that can be inserted
in other places:

.. code-block:: genshitext

  #def greeting(name)
    Hello, ${name}!
  #end
  ${greeting('world')}
  ${greeting('everyone else')}

The above would be rendered to::

    Hello, world!
    Hello, everyone else!

If a macro doesn't require parameters, it can be defined as well as called
without the parenthesis. For example:

.. code-block:: genshitext

  #def greeting
    Hello, world!
  #end
  ${greeting}

The above would be rendered to::

    Hello, world!


.. _includes:
.. _`#include`:

``#include``
------------

To reuse common parts of template text across template files, you can include
other files using the ``#include`` directive:

.. code-block:: genshitext

  #include "base.txt"

Any content included this way is inserted into the generated output. The
included template sees the context data as it exists at the point of the
include. `Macros`_ in the included template are also available to the including
template after the point it was included.

Include paths are relative to the filename of the template currently being
processed. So if the example above was in the file "``myapp/mail.txt``"
(relative to the template search path), the include directive would look for
the included file at "``myapp/base.txt``". You can also use Unix-style
relative paths, for example "``../base.txt``" to look in the parent directory.

Just like other directives, the argument to the ``#include`` directive accepts
any Python expression, so the path to the included template can be determined
dynamically:

.. code-block:: genshitext

  #include '%s.txt' % filename

Note that a ``TemplateNotFound`` exception is raised if an included file can't
be found.

.. note:: The include directive for text templates was added in Genshi 0.5.


Variable Binding
================

.. _`#with`:

``#with``
-----------

The ``#with`` directive lets you assign expressions to variables, which can
be used to make expressions inside the directive less verbose and more
efficient. For example, if you need use the expression ``author.posts`` more
than once, and that actually results in a database query, assigning the results
to a variable using this directive would probably help.

For example:

.. code-block:: genshitext

  Magic numbers!
  #with y=7; z=x+10
    $x $y $z
  #end

Given ``x=42`` in the context data, this would produce::

  Magic numbers!
    42 7 52

Note that if a variable of the same name already existed outside of the scope
of the ``#with`` directive, it will **not** be overwritten. Instead, it will
have the same value it had prior to the ``#with`` assignment. Effectively,
this means that variables are immutable in Genshi.


.. _comments:

--------
Comments
--------

Lines where the first non-whitespace characters are ``##`` are removed from
the output, and can thus be used for comments. This can be escaped using a
backslash.
Copyright (C) 2012-2017 Edgewall Software