Edgewall Software

Changes between Initial Version and Version 1 of WorkInProgress/PluggableDirectivesLibraries/TextTemplates


Ignore:
Timestamp:
Jun 11, 2010, 8:52:57 PM (14 years ago)
Author:
Carsten Klein <carsten.klein@…>
Comment:

original content of the text-templates documentation from 0.6 trunk

Legend:

Unmodified
Added
Removed
Modified
  • WorkInProgress/PluggableDirectivesLibraries/TextTemplates

    v1 v1  
     1.. -*- mode: rst; encoding: utf-8 -*-
     2
     3=============================
     4Genshi Text Template Language
     5=============================
     6
     7In addition to the XML-based template language, Genshi provides a simple
     8text-based template language, intended for basic plain text generation needs.
     9The language is similar to the Django_ template language.
     10
     11This document describes the template language and will be most useful as
     12reference to those developing Genshi text templates. Templates are text files of
     13some kind that include processing directives_ that affect how the template is
     14rendered, and template expressions that are dynamically substituted by
     15variable data.
     16
     17See `Genshi Templating Basics <templates.html>`_ for general information on
     18embedding Python code in templates.
     19
     20.. note:: Actually, Genshi currently has two different syntaxes for text
     21          templates languages: One implemented by the class ``OldTextTemplate``
     22          and another implemented by ``NewTextTemplate``. This documentation
     23          concentrates on the latter, which is planned to completely replace the
     24          older syntax. The older syntax is briefly described under legacy_.
     25
     26.. _django: http://www.djangoproject.com/
     27
     28.. contents:: Contents
     29   :depth: 3
     30.. sectnum::
     31
     32
     33.. _`directives`:
     34
     35-------------------
     36Template Directives
     37-------------------
     38
     39Directives are template commands enclosed by ``{% ... %}`` characters. They can
     40affect how the template is rendered in a number of ways: Genshi provides
     41directives for conditionals and looping, among others.
     42
     43Each directive must be terminated using an ``{% end %}`` marker. You can add
     44a string inside the ``{% end %}`` marker, for example to document which
     45directive is being closed, or even the expression associated with  that
     46directive. Any text after ``end`` inside the delimiters is  ignored,  and
     47effectively treated as a comment.
     48
     49If you want to include a literal delimiter in the output, you need to escape it
     50by prepending a backslash character (``\``).
     51
     52
     53Conditional Sections
     54====================
     55
     56.. _`if`:
     57
     58``{% if %}``
     59------------
     60
     61The content is only rendered if the expression evaluates to a truth value:
     62
     63.. code-block:: genshitext
     64
     65  {% if foo %}
     66    ${bar}
     67  {% end %}
     68
     69Given the data ``foo=True`` and ``bar='Hello'`` in the template context, this
     70would produce::
     71
     72    Hello
     73
     74
     75.. _`choose`:
     76.. _`when`:
     77.. _`otherwise`:
     78
     79``{% choose %}``
     80----------------
     81
     82The ``choose`` directive, in combination with the directives ``when`` and
     83``otherwise``, provides advanced contional processing for rendering one of
     84several alternatives. The first matching ``when`` branch is rendered, or, if
     85no ``when`` branch matches, the ``otherwise`` branch is be rendered.
     86
     87If the ``choose`` directive has no argument the nested ``when`` directives will
     88be tested for truth:
     89
     90.. code-block:: genshitext
     91
     92  The answer is:
     93  {% choose %}
     94    {% when 0 == 1 %}0{% end %}
     95    {% when 1 == 1 %}1{% end %}
     96    {% otherwise %}2{% end %}
     97  {% end %}
     98
     99This would produce the following output::
     100
     101  The answer is:
     102    1
     103
     104If the ``choose`` does have an argument, the nested ``when`` directives will
     105be tested for equality to the parent ``choose`` value:
     106
     107.. code-block:: genshitext
     108
     109  The answer is:
     110  {% choose 1 %}\
     111    {% when 0 %}0{% end %}\
     112    {% when 1 %}1{% end %}\
     113    {% otherwise %}2{% end %}\
     114  {% end %}
     115
     116This would produce the following output::
     117
     118  The answer is:
     119      1
     120
     121
     122Looping
     123=======
     124
     125.. _`for`:
     126
     127``{% for %}``
     128-------------
     129
     130The content is repeated for every item in an iterable:
     131
     132.. code-block:: genshitext
     133
     134  Your items:
     135  {% for item in items %}\
     136    * ${item}
     137  {% end %}
     138
     139Given ``items=[1, 2, 3]`` in the context data, this would produce::
     140
     141  Your items
     142    * 1
     143    * 2
     144    * 3
     145
     146
     147Snippet Reuse
     148=============
     149
     150.. _`def`:
     151.. _`macros`:
     152
     153``{% def %}``
     154-------------
     155
     156The ``def`` directive can be used to create macros, i.e. snippets of template
     157text that have a name and optionally some parameters, and that can be inserted
     158in other places:
     159
     160.. code-block:: genshitext
     161
     162  {% def greeting(name) %}
     163    Hello, ${name}!
     164  {% end %}
     165  ${greeting('world')}
     166  ${greeting('everyone else')}
     167
     168The above would be rendered to::
     169
     170    Hello, world!
     171    Hello, everyone else!
     172
     173If a macro doesn't require parameters, it can be defined without the
     174parenthesis. For example:
     175
     176.. code-block:: genshitext
     177
     178  {% def greeting %}
     179    Hello, world!
     180  {% end %}
     181  ${greeting()}
     182
     183The above would be rendered to::
     184
     185    Hello, world!
     186
     187
     188.. _includes:
     189.. _`include`:
     190
     191``{% include %}``
     192-----------------
     193
     194To reuse common parts of template text across template files, you can include
     195other files using the ``include`` directive:
     196
     197.. code-block:: genshitext
     198
     199  {% include base.txt %}
     200
     201Any content included this way is inserted into the generated output. The
     202included template sees the context data as it exists at the point of the
     203include. `Macros`_ in the included template are also available to the including
     204template after the point it was included.
     205
     206Include paths are relative to the filename of the template currently being
     207processed. So if the example above was in the file "``myapp/mail.txt``"
     208(relative to the template search path), the include directive would look for
     209the included file at "``myapp/base.txt``". You can also use Unix-style
     210relative paths, for example "``../base.txt``" to look in the parent directory.
     211
     212Just like other directives, the argument to the ``include`` directive accepts
     213any Python expression, so the path to the included template can be determined
     214dynamically:
     215
     216.. code-block:: genshitext
     217
     218  {% include ${'%s.txt' % filename} %}
     219
     220Note that a ``TemplateNotFound`` exception is raised if an included file can't
     221be found.
     222
     223.. note:: The include directive for text templates was added in Genshi 0.5.
     224
     225
     226Variable Binding
     227================
     228
     229.. _`with`:
     230
     231``{% with %}``
     232--------------
     233
     234The ``{% with %}`` directive lets you assign expressions to variables, which can
     235be used to make expressions inside the directive less verbose and more
     236efficient. For example, if you need use the expression ``author.posts`` more
     237than once, and that actually results in a database query, assigning the results
     238to a variable using this directive would probably help.
     239
     240For example:
     241
     242.. code-block:: genshitext
     243
     244  Magic numbers!
     245  {% with y=7; z=x+10 %}
     246    $x $y $z
     247  {% end %}
     248
     249Given ``x=42`` in the context data, this would produce::
     250
     251  Magic numbers!
     252    42 7 52
     253
     254Note that if a variable of the same name already existed outside of the scope
     255of the ``with`` directive, it will **not** be overwritten. Instead, it will
     256have the same value it had prior to the ``with`` assignment. Effectively,
     257this means that variables are immutable in Genshi.
     258
     259
     260.. _whitespace:
     261
     262---------------------------
     263White-space and Line Breaks
     264---------------------------
     265
     266Note that space or line breaks around directives is never automatically removed.
     267Consider the following example:
     268
     269.. code-block:: genshitext
     270
     271  {% for item in items %}
     272    {% if item.visible %}
     273      ${item}
     274    {% end %}
     275  {% end %}
     276
     277This will result in two empty lines above and beneath every item, plus the
     278spaces used for indentation. If you want to supress a line break, simply end
     279the line with a backslash:
     280
     281.. code-block:: genshitext
     282
     283  {% for item in items %}\
     284    {% if item.visible %}\
     285      ${item}
     286    {% end %}\
     287  {% end %}\
     288
     289Now there would be no empty lines between the items in the output. But you still
     290get the spaces used for indentation, and because the line breaks are removed,
     291they actually continue and add up between lines. There are numerous ways to
     292control white-space in the output while keeping the template readable, such as
     293moving the indentation into the delimiters, or moving the end delimiter on the
     294next line, and so on.
     295
     296
     297.. _comments:
     298
     299--------
     300Comments
     301--------
     302
     303Parts in templates can be commented out using the delimiters ``{# ... #}``.
     304Any content in comments are removed from the output.
     305
     306.. code-block:: genshitext
     307
     308  {# This won't end up in the output #}
     309  This will.
     310
     311Just like directive delimiters, these can be escaped by prefixing with a
     312backslash.
     313
     314.. code-block:: genshitext
     315
     316  \{# This *will* end up in the output, including delimiters #}
     317  This too.
     318
     319
     320.. _legacy:
     321
     322---------------------------
     323Legacy Text Template Syntax
     324---------------------------
     325
     326The syntax for text templates was redesigned in version 0.5 of Genshi to make
     327the language more flexible and powerful. The older syntax is based on line
     328starting with dollar signs, similar to e.g. Cheetah_ or Velocity_.
     329
     330.. _cheetah: http://cheetahtemplate.org/
     331.. _velocity: http://jakarta.apache.org/velocity/
     332
     333A simple template using the old syntax looked like this:
     334
     335.. code-block:: genshitext
     336
     337  Dear $name,
     338 
     339  We have the following items for you:
     340  #for item in items
     341   * $item
     342  #end
     343 
     344  All the best,
     345  Foobar
     346
     347Beyond the requirement of putting directives on separate lines prefixed with
     348dollar signs, the language itself is very similar to the new one. Except that
     349comments are lines that start with two ``#`` characters, and a line-break at the
     350end of a directive is removed automatically.
     351
     352.. note:: If you're using this old syntax, it is strongly recommended to
     353          migrate to the new syntax. Simply replace any references to
     354          ``TextTemplate`` by ``NewTextTemplate`` (and also change the
     355          text templates, of course). On the other hand, if you want to stick
     356          with the old syntax for a while longer, replace references to
     357          ``TextTemplate`` by ``OldTextTemplate``; while ``TextTemplate`` is
     358          still an alias for the old language at this point, that will change
     359          in a future release. But also note that the old syntax may be
     360          dropped entirely in a future release.