Mercurial > genshi > genshi-test
diff doc/templates.txt @ 720:f0bb2c5ea0ff experimental-newctxt
newctxt branch: Merged revisions [678:835] via svnmerge from [source:trunk].
author | cmlenz |
---|---|
date | Fri, 11 Apr 2008 08:42:11 +0000 |
parents | 6e21c89d9255 |
children |
line wrap: on
line diff
--- a/doc/templates.txt +++ b/doc/templates.txt @@ -116,9 +116,12 @@ >>> from genshi.template import MarkupTemplate >>> tmpl = MarkupTemplate('<h1>Hello, $name!</h1>') >>> stream = tmpl.generate(name='world') - >>> print stream.render() + >>> print stream.render('xhtml') <h1>Hello, world!</h1> +.. note:: See the Serialization_ section of the `Markup Streams`_ page for + information on configuring template output options. + Using a text template is similar: .. code-block:: pycon @@ -126,13 +129,15 @@ >>> from genshi.template import TextTemplate >>> tmpl = TextTemplate('Hello, $name!') >>> stream = tmpl.generate(name='world') - >>> print stream.render() + >>> print stream Hello, world! -.. note:: See the Serialization_ section of the `Markup Streams`_ page for - information on configuring template output options. +.. note:: If you want to use text templates, you should consider using the + ``NewTextTemplate`` class instead of simply ``TextTemplate``. See + the `Text Template Language`_ page. .. _serialization: streams.html#serialization +.. _`Text Template Language`: text-templates.html .. _`Markup Streams`: streams.html Using a template loader provides the advantage that “compiled” templates are @@ -203,8 +208,8 @@ Code Blocks =========== -XML templates also support full Python code blocks using the ``<?python ?>`` -processing instruction: +Templates also support full Python code blocks, using the ``<?python ?>`` +processing instruction in XML templates: .. code-block:: genshi @@ -212,21 +217,38 @@ <?python from genshi.builder import tag def greeting(name): - return tag.b('Hello, %s!' % name') ?> + return tag.b('Hello, %s!' % name) ?> ${greeting('world')} </div> This will produce the following output: -.. code-block:: genshi +.. code-block:: xml <div> <b>Hello, world!</b> </div> +In text templates (although only those using the new syntax introduced in +Genshi 0.5), code blocks use the special ``{% python %}`` directive: + +.. code-block:: genshitext + + {% python + from genshi.builder import tag + def greeting(name): + return 'Hello, %s!' % name + %} + ${greeting('world')} + +This will produce the following output:: + + Hello, world! + + Code blocks can import modules, define classes and functions, and basically do anything you can do in normal Python code. What code blocks can *not* do is to -produce content that is included directly in the generated page. +produce content that is emitted directly tp the generated output. .. note:: Using the ``print`` statement will print to the standard output stream, just as it does for other Python code in your application. @@ -248,7 +270,11 @@ into a sandboxable template engine; there are sufficient ways to do harm even using plain expressions. -.. note:: Code blocks are not currently supported in text templates. +.. warning:: Unfortunately, code blocks are severely limited when running + under Python 2.3: For example, it is not possible to access + variables defined in outer scopes. If you plan to use code blocks + extensively, it is strongly recommended that you run Python 2.4 + or later. .. _`error handling`: @@ -256,13 +282,56 @@ Error Handling ============== -By default, Genshi allows you to access variables that are not defined, without -raising a ``NameError`` exception as regular Python code would: +By default, Genshi raises an ``UndefinedError`` if a template expression +attempts to access a variable that is not defined: .. code-block:: pycon >>> from genshi.template import MarkupTemplate >>> tmpl = MarkupTemplate('<p>${doh}</p>') + >>> tmpl.generate().render('xhtml') + Traceback (most recent call last): + ... + UndefinedError: "doh" not defined + +You can change this behavior by setting the variable lookup mode to "lenient". +In that case, accessing undefined variables returns an `Undefined` object, +meaning that the expression does not fail immediately. See below for details. + +If you need to check whether a variable exists in the template context, use the +defined_ or the value_of_ function described below. To check for existence of +attributes on an object, or keys in a dictionary, use the ``hasattr()``, +``getattr()`` or ``get()`` functions, or the ``in`` operator, just as you would +in regular Python code: + + >>> from genshi.template import MarkupTemplate + >>> tmpl = MarkupTemplate('<p>${defined("doh")}</p>') + >>> print tmpl.generate().render('xhtml') + <p>False</p> + +.. note:: Lenient error handling was the default in Genshi prior to version 0.5. + Strict mode was introduced in version 0.4, and became the default in + 0.5. The reason for this change was that the lenient error handling + was masking actual errors in templates, thereby also making it harder + to debug some problems. + + +.. _`lenient`: + +Lenient Mode +------------ + +If you instruct Genshi to use the lenient variable lookup mode, it allows you +to access variables that are not defined, without raising an ``UndefinedError``. + +This mode can be chosen by passing the ``lookup='lenient'`` keyword argument to +the template initializer, or by passing the ``variable_lookup='lenient'`` +keyword argument to the ``TemplateLoader`` initializer: + +.. code-block:: pycon + + >>> from genshi.template import MarkupTemplate + >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='lenient') >>> print tmpl.generate().render('xhtml') <p></p> @@ -272,7 +341,7 @@ .. code-block:: pycon >>> from genshi.template import MarkupTemplate - >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>') + >>> tmpl = MarkupTemplate('<p>${doh.oops}</p>', lookup='lenient') >>> print tmpl.generate().render('xhtml') Traceback (most recent call last): ... @@ -284,42 +353,14 @@ .. code-block:: pycon >>> from genshi.template import MarkupTemplate - >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>') + >>> tmpl = MarkupTemplate('<p>${type(doh) is not Undefined}</p>', + ... lookup='lenient') >>> print tmpl.generate().render('xhtml') <p>False</p> Alternatively, the built-in functions defined_ or value_of_ can be used in this case. -Strict Mode ------------ - -In addition to the default "lenient" error handling, Genshi lets you use a less -forgiving mode if you prefer errors blowing up loudly instead of being ignored -silently. - -This mode can be chosen by passing the ``lookup='strict'`` keyword argument to -the template initializer, or by passing the ``variable_lookup='strict'`` keyword -argument to the ``TemplateLoader`` initializer: - -.. code-block:: pycon - - >>> from genshi.template import MarkupTemplate - >>> tmpl = MarkupTemplate('<p>${doh}</p>', lookup='strict') - >>> print tmpl.generate().render('xhtml') - Traceback (most recent call last): - ... - UndefinedError: "doh" not defined - -When using strict mode, any reference to an undefined variable, as well as -trying to access an non-existing item or attribute of an object, will cause an -``UndefinedError`` to be raised immediately. - -.. note:: While this mode is currently not the default, it may be promoted to - the default in future versions of Genshi. In general, the default - lenient error handling mode can be considered dangerous as it silently - ignores typos. - Custom Modes ------------