.. -*- mode: rst; encoding: utf-8 -*- ========================== Kid Language Specification ========================== :Author: `Ryan Tomayko`_ :Contact: rtomayko@gmail.com :Revision: 4 :Date: $Date: 2005-11-10 07:52:40 -0500 (Thu, 10 Nov 2005) $ :Copyright: 2005, Ryan Tomayko :Other Formats: Text__ .. __: language.txt .. _Ryan Tomayko: http://naeblis.cx/rtomayko/ Kid is a simple XML based template language that uses embedded Python_ to do cool stuff. The syntax was inspired by a number of existing template languages, namely XSLT_, TAL_, and PHP_. .. _python: http://www.python.org/ .. _xslt: http://www.w3.org/TR/xslt .. _tal: http://www.zope.org/Wikis/DevSite/Projects/ZPT/TAL .. _php: http://www.php.net/ This document describes the template language and will be most useful as reference to those developing Kid templates. For information about using templates from Python, the command line, or in web environments, see the `User's Guide`__. .. __: guide.html .. contents:: Contents :depth: 2 .. sectnum:: Synopsis ======== ::
These are some of my favorite fruits:
Good for you!
Yields something like this::These are some of my favorite fruits:
Good for you!
The Kid Namespace ================= All attributes described in this document must belong to the following namespace:: http://purl.org/kid/ns# The namespace prefix ``py`` is used throughout this document to indicate that an item belongs to the Kid/Python namespace. Embedding Code Blocks (````) ====================================== The ```` processing instruction (PI) contains Python code and *MAY* occur anywhere that is legal for processing instructions to occur in an XML document. The rules for executing code found in a ```` PI is as follows: 1. ```` PIs located outside of the document element (e.g. root element) contain *Document Level* code. This code *SHOULD* be executed in a global, shared scope for the document. The code *SHOULD* be executed once when the template is loaded and shared between multiple invocations of the template. 2. ```` PIs located within the document element contain *Local Level* code. This code is executed each time the document is processed with a local scope specific to the invocation and the shared document level global scope. *Document Level* and *Local Level* code work exactly like *Module Level* and *Function Level* code in normal Python modules. For example, the following Kid template:: May be considered equivalent to the following Python module:: x = 0 y = 0 def expand(handler): handler.startDocument() handler.startElement('html') x = 1 if x == 1: x = 10 handler.element('p', content=x) # output p element with x as value global y y = 30 handler.element('p', content=y) # output p element with value of y handler.endElement('html') handler.endDocument() ```` PIs may contain any legal Python language construct including functions, classes, lamda forms, etc. :: Single line ```` PIs are okay too:: .. _Content Producing Construct: Content Producing Constructs ============================ There are multiple methods of generating content output from a template: ``py:content``, ``py:replace``, ``py:attrs``, and ``${}`` substitution. Each of these syntaxes have the same rules for what types of objects may result from the Python expression they contain. ``str``, ``unicode`` The string is inserted as XML CDATA. That is, it is non-parsable character data that does not contain markup. The following characters are encoded as XML entities when serialized: '<', '&'. Attribute values containing content also encode the quote character: '"'. ``ElementTree.Element`` When an ``ElementTree.Element`` is referenced from a content producing construct, the item is inserted into the document literally, i.e. it is not encoded as text, but becomes part of the output structure. The ``XML()`` and ``document()`` functions can be used to turn a string into structured content and to retrieve an XML document from a URL, respectively. Note that attribute values *MUST NOT* reference structured content. This applies to ``py:attrs`` and using ``${}`` substitution in attribute values. *sequence* If a sequence type (``list``, ``tuple``, or other iterable) is referenced, the rules are applied to each of the items in the sequence. For example, you could reference a list containing an ``Element`` and a string. Other If the result of evaluating the expression is any other type, an attempt is made to coerce the value to unicode as if by calling ``unicode(expr)`` and processing continues as if the object were a string or unicode object initially. .. _Expression Substitution: Python Expression Substitution (``${expr}``) ============================================ Attributes not belonging to the Kid namespace and text content *MAY* embed Python expressions by enclosing the expression within a dollar sign followed by curly braces: ``${expr}``. The result of evaluating the expression(s) is substituted with the rest of the attribute value or text content following rules defined for `Content Producing Constructs`_. :: ... ... would result in:: ... If an attribute value consists purely of substitution expressions and all expressions evaluate to ``None``, the attribute is removed. This can be avoided by using ``expr or ''`` to force a zero length string to be returned instead of ``None``. For example:: ... ... would result in:: ... However, this:: ... ... results in:: ... Identifier Shortcut (``$name``) ------------------------------- For simple expressions consisting entirely variable names and object access operators (.), the curly braces may be omitted:: Dots are allowed too: $object.another.attribute However, it is good practice to use the curly brace form as it sets the substitution off from the other text a bit more providing a stronger visual clue as to what's going on. Escaping (``$$``) ----------------- ``$$`` is an escape. ``$${bla}`` will output ``${bla}``. Default Imports =============== All templates have a few default imports for convenience. ``XML()`` function ------------------ `Expression substitution`_, `py:content`_, and `py:replace`_ encode strings as text. That is, text is encoded according to the rules of the XML specification, which includes, among other things, replacing the literal characters ``<`` and ``&`` with their encoded counterparts (``<`` ``&``). If you have XML stored as a string and want it to be output as XML and not encoded text, you need to pass the string to the ``XML`` function. For example, let's say there is a function, ``hello``, that returns XML data that should be embedded in template output (let's say it returns ``${hello()}
The result would be::<hello>world<hello>
Calling the ``XML`` function would have given us the result we intended::${XML(hello())}
::X bottles of beer on the wall, X bottles of beer on the wall, take one down, pass it around, X - 1 bottles of beer on the wall.
The ``py:for`` attribute is the first attribute to be processed if present. All other ``py:`` attributes are processed for each iteration of the loop. .. _`py:if`: Conditionals (``py:if``) ------------------------ ::Python seems to be handling multiplication okay.
The ``py:if`` attribute is processed after the ``py:for`` attribute and is evaluated for each iteration. If the result of evaluating ``expr`` as a boolean expression is false in Python, no further ``py:`` attributes are processed for the current iteration or, if not in a ``py:for``, at all. .. note:: Evaluated as a boolean expression in Python, ``None``, ``False``, ``[]``, ``()``, ``{}``, ``0``, and ``''`` are all considered to be false. .. _`py:content`: Dynamic Content (``py:content``) -------------------------------- ::The Time
Results in::Tues, Jun 26, 2004 02:03:53 AM
``py:content`` is a `Content Producing Construct`_ and can output both character and structured data. .. _`py:replace`: Replacing Content (``py:replace``) ---------------------------------- ::...
... results in::10
... and is equivelant to specifying::...
The ``py:replace`` attribute is processed after the ``py:for`` and ``py:if`` attributes. ``py:strip`` and ``py:content`` attributes are not processed and are discarded. ``py:replace`` is a `Content Producing Construct`_ and can output both character and structured data. .. _`py:strip`: Stripping Tags (``py:strip``) ----------------------------- ::Key | Value |
---|---|
Good
Good Morning!
The obvious question at this point is how to reuse Match Templates? The example above demonstrates the use of a Match Template from the same main template but it is often desirable to have "libraries" of Match Templates that could be used by multiple individual templates. The answer is to have the main template extend_ a common template containing the Match Templates needed. We can rewrite the above example as two separate templates: ``main.kid`` and ``common.kid``. The common template would look like this:: And the main template would look like this::
Good
The following errors were found:
${ display_errors(["Field is required", "Must be phone number.."]) } The ``errors`` item is transformed to ``ERRORS`` and the error list is displayed. Both the match template and the named template function are available in the derived template as if they were defined locally. .. _`order`: Processing Order ================ The order that ``py:`` attributes are processed is as follows: 1. ``py:def`` 2. ``py:match`` 3. ``py:for`` 4. ``py:if`` 5. ``py:replace`` 6. ``py:strip`` 7. ``py:attrs`` 8. ``py:content`` Attribute substitution occurs after all other attributes are processed and MUST NOT be processed for ``py:`` attributes. Revision History ================ Revision 4 (Kid v0.6) --------------------- * Add ``py:extends``. * Add ``py:match``. * Add ``py:attrs``. * ``py:omit`` renamed ``py:strip``. * Kid namespace changed from ``http://nabelis.cx/ns/kid#`` to ``http://purl.org/kid/ns#``. * Removed requirement of ```` blocks to start with a comment. * Expression substitution syntax changed from ``{}`` to ``${}``. Revision 3 (Kid v0.5) --------------------- * Changed processing instruction from ```` to ````. * Changed namespace prefixes from ``kid:`` to ``py:``. Revision 2 ---------- * Added detail for each attribute on when it is processed in relation to other attributes and whether the result of other attributes modify behavior. * Fixed a few minor typos and grammatical issues. * Added editorial notes where things are a bit shaky. Revision 1 ---------- * Initial public version.