PTL: Python Template Language
=============================

PTL is the templating language used by Quixote.  PTL inverts the usual
model used by web templating languages -- embed a real programming
language in HTML -- by merely tweaking Python to make it easier to
generate HTML pages (or other forms of text).  In other words, PTL is
basically Python with a novel way to specify function return values.
Specifically, PTL has one extra keyword -- ``template`` -- and the value
of expressions inside templates are kept, not discarded.  Here's a
sample template::

    template foo (x, y = 5):
        "This is a chunk of static text."
        greeting = "hello world" # statement, no PTL output
        print 'Input values:', x, y
        z = x + y
        """You can plug in variables like x (%s)
    in a variety of ways.""" % x

        "\n\n"
        "Whitespace is important in generated text.\n"
        "z = "
        str(z)
        ", but y is "
        y
        "."

Templates are the PTL analogue to Python functions.  Templates are
defined using the ``template`` keyword, obviously, and they can't have
docstrings, but otherwise they follow Python's syntactic rules:
indentation indicates scoping, single-quoted and triple-quoted strings
can be used, the same rules for continuing lines apply, and so forth.
PTL also follows all the expected semantics of normal Python code: so
templates can have parameters, and the parameters can have default
values, be treated as keyword arguments, etc.

The difference between a template and a regular Python function is that
inside a template the result of expressions are saved as the return
value of that template.  Look at the first part of the example again::

    template foo (x, y = 5):
        "This is a chunk of static text."
        greeting = "hello world" # statement, no PTL output
        print 'Input values:', x, y
        z = x + y
        """You can plug in variables like x (%s)
    in a variety of ways.""" % x

Calling this template with ``foo(1,2)`` results in the following
string::

    This is a chunk of static text.You can plug in variables like x (1)
    in a variety of ways.

Normally when Python evaluates expressions inside functions, it just
discards their values, but in PTL the value is converted to a string
using ``str()`` and appended to the template's return value.  There's a
single exception to this rule: ``None`` is the only value that's ever
ignored, adding nothing to the output.  (If this weren't the case,
calling methods or functions that return ``None`` would require
assigning their value to a variable.  You'd have to write ``dummy =
list.sort()`` in PTL code, which would be strange and confusing.)

The initial string in a template isn't treated as a docstring, but is
just incorporated in the generated output; therefore, templates can't
have docstrings.  No whitespace is ever automatically added to the
output, resulting in ``...text.You can ...`` from the example.  You'd
have to add an extra space to one of the string literals to correct
this.

The assignment to the ``greeting`` local variable is a statement, not an
expression, so it doesn't return a value and produces no output.  The
output from the ``print`` statement will be printed as usual, but won't
go into the string generated by the template.  Quixote directs standard
output into Quixote's debugging log; if you're using PTL on its own, you
should consider doing something similar.  ``print`` should never be used
to generate output returned to the browser, only for adding debugging
traces to a template.

Inside templates, you can use all of Python's control-flow statements::

    template numbers(n):
        for i in range(n):
            i
            " " # PTL does not add any whitespace

Calling ``numbers(5)`` will return the string ``"1 2 3 4 5 "``.  You can
also have conditional logic or exception blocks::

    template international_hello(language):
        if language == "english":
            "hello"
        elif language == "french":
            "bonjour"
        else:
            raise ValueError, "I don't speak %s" % language

PTL templates are kept in files with the extension .ptl.  Like Python
files, they are byte-compiled on import, and the byte-code is written to
a compiled file with the extension ``.ptlc``.  Since vanilla Python
doesn't know anything about PTL, Quixote provides an import hook to let
you import PTL files just like regular Python modules.  The standard way
to install this import hook is by calling the ``enable_ptl()`` function::

    from quixote import enable_ptl
    enable_ptl()

(Note: if you're using ZODB, always import ZODB *before* installing the
PTL import hook.  There's some interaction which causes importing the
TimeStamp module to fail when the PTL import hook is installed; we
haven't debugged the problem.)

Once the import hook is installed, PTL files can be imported as if they
were Python modules.  If all the example templates shown here were put
into a file named ``foo.ptl``, you could then write Python code that did
this::

    from foo import numbers
    def f():
        return numbers(10)

You may want to keep this little function in your ``PYTHONSTARTUP``
file::

    def ptl():
        try:
            import ZODB
        except ImportError:
            pass
        from quixote import enable_ptl
        enable_ptl()

This is useful if you want to interactively play with a PTL module.


$Id: PTL.txt,v 1.13 2002/10/02 14:52:47 gward Exp $
