Template classes
================

The ``chameleon.zpt`` package provides the ``PageTemplate`` and
``PageTemplateFile`` classes which allow easy usage of templates in
your application.

Usage
-----

  >>> from chameleon.zpt.template import PageTemplate
  
  >>> print PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml">
  ...   Hello World!
  ... </div>""")()
  <div>
    Hello World!
  </div>

  >>> from chameleon.zpt.template import PageTemplateFile
  >>> from chameleon.zpt import tests
  
  >>> path = tests.__path__[0]
  >>> t = PageTemplateFile(path+'/helloworld.pt')
  >>> print t()
  <div>
    Hello World!
  </div>

  >>> import os
  >>> t.filename.startswith(os.sep)
  True

METAL template integration
--------------------------

Page templates expose macros in their ``macros`` attribute.

  >>> main = PageTemplate("""\
  ... <html xmlns="http://www.w3.org/1999/xhtml"
  ...       xmlns:tal="http://xml.zope.org/namespaces/tal"
  ...       xmlns:metal="http://xml.zope.org/namespaces/metal"
  ...       metal:define-macro="master">
  ...   <div metal:define-slot="content">
  ...       I will be replaced
  ...   </div>
  ... </html>""")

  >>> content = PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal"
  ...      xmlns:metal="http://xml.zope.org/namespaces/metal"
  ...      metal:use-macro="main.macros['master']">
  ...   <div metal:fill-slot="content">
  ...       I replace you.
  ...   </div>
  ... </div>""")

  >>> print content(main=main)
  <html>
    <div>
         I replace you.
    </div>
  </html>  
  
Error handling
--------------

When an exception is raised which does not expose a bug in the TAL
translation machinery, we expect the exception to contain the part of
the template source that caused the exception.

Exception while evaluating expression:

  >>> PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:content="range()" />
  ... </div>""").render()
  Traceback (most recent call last):
    ...
  RuntimeError: Caught exception rendering template.
    ...
  TypeError: range expected at least 1 arguments, got 0

Exception while evaluating definition:

  >>> PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:define="dummy range()" />
  ... </div>""").render()
  Traceback (most recent call last):
    ...
  RuntimeError: Caught exception rendering template.
    ...
  TypeError: range expected at least 1 arguments, got 0

Exception while evaluating interpolation:

  >>> PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span>${range()}</span>
  ... </div>""").render()
  Traceback (most recent call last):
    ...
  RuntimeError: Caught exception rendering template.
    ...
  TypeError: range expected at least 1 arguments, got 0
