diff doc/text-templates.txt @ 241:4d81439bc097 trunk

* Added basic documentation for the text-based template language. * Directives in text templates are now closed with a simple `#end` line instead of the longer `#end<name>`.
author cmlenz
date Wed, 13 Sep 2006 14:52:58 +0000
parents
children fa07ab5a7e53
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/doc/text-templates.txt
@@ -0,0 +1,292 @@
+.. -*- 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 XML files of some
+kind (such as XHTML) that include processing directives_ (elements or
+attributes identified by a separate namespace) that affect how the template is
+rendered, and template expressions_ that are dynamically substituted by
+variable data.
+
+
+.. contents:: Contents
+   :depth: 3
+.. sectnum::
+
+----------
+Python API
+----------
+
+The Python code required for templating with Genshi is generally based on the
+following pattern:
+
+* Attain a ``Template`` object from a string or file object containing the
+  template source. This can either be done directly, or through a
+  ``TemplateLoader`` instance.
+* Call the ``generate()`` method of the template, passing any data that should
+  be made available to the template as keyword arguments.
+* Serialize the resulting stream using its ``render()`` method.
+
+For example::
+
+  from genshi.template import TextTemplate
+
+  tmpl = TextTemplate('$title')
+  stream = tmpl.generate(title='Hello, world!')
+  print stream.render('text')
+
+That code would produce the following output::
+
+  Hello, world!
+
+Using a template loader provides the advantage that “compiled” templates are
+automatically cached, and only parsed again when the template file changes::
+
+  from genshi.template import TemplateLoader
+
+  loader = TemplateLoader([templates_dir])
+  tmpl = loader.load('test.txt' cls=TextTemplate)
+  stream = tmpl.generate(title='Hello, world!')
+  print stream.render('text')
+
+
+.. _`expressions`:
+
+--------------------
+Template Expressions
+--------------------
+
+Python_ expressions can be used in text and attribute values. An expression is
+substituted with the result of its evaluation against the template data.
+Expressions need to prefixed with a dollar sign (``$``) and usually enclosed in
+curly braces (``{…}``).
+
+.. _python: http://www.python.org/
+
+If the expression starts with a letter and contains only letters and digits,
+the curly braces may be omitted. In all other cases, the braces are required
+so that the template processors knows where the expression ends::
+
+  >>> from genshi.template import TextTemplate
+  >>> tmpl = TextTemplate('${items[0].capitalize()} item')
+  >>> print tmpl.generate(items=['first', 'second'])
+  First item
+
+Expressions support the full power of Python. In addition, it is possible to
+access items in a dictionary using “dotted notation” (i.e. as if they were
+attributes), and vice-versa (i.e. access attributes as if they were items in
+a dictionary)::
+
+  >>> from genshi.template import TextTemplate
+  >>> tmpl = TextTemplate('${dict.foo}')
+  >>> print tmpl.generate(dict={'foo': 'bar'})
+  bar
+
+
+.. _`directives`:
+
+-------------------
+Template Directives
+-------------------
+
+Directives are lines starting with a ``#`` character followed 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.
+
+For example::
+
+  #if foo
+    Bar
+  #end
+
+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.
+
+
+Conditional Sections
+====================
+
+.. _`#if`:
+
+``#if``
+---------
+
+The content is only rendered if the expression evaluates to a truth value::
+
+  #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::
+
+  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::
+
+  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::
+
+  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::
+
+  #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::
+
+  #def greeting
+    Hello, world!
+  #end
+  ${greeting}
+
+The above would be rendered to::
+
+    Hello, world!
+
+
+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::
+
+  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