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

chameleon.core.template.Template
--------------------------------

  >>> from chameleon.core.template import Template
  >>> from chameleon.core.testing import mock_parser
  
  >>> print Template("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml">
  ...   Hello World!
  ... </div>""", mock_parser)()
  <div>
    Hello World!
  </div>

chameleon.core.template.TemplateFile
------------------------------------

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

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

Macros
------

In this package, macros are supported only as a framework for actual
language implementations.

  >>> from chameleon.core.template import Macros
  
  >>> def render(name, parameters={}):
  ...     print parameters.items()
  
  >>> Macros(render).bind(test=u"Hello, world!")[""].render()
  [('test', u'Hello, world!')]
  
XInclude support
----------------

  >>> template = TemplateFile(path+"/xinclude1.pt", mock_parser)
  >>> print template()
  <div>
    <div>
    <span>Hello, world!</span>
    </div>
  </div>

  >>> from cPickle import dumps, loads
  >>> for key, bct in template.registry.items():
  ...     template.registry[key] = loads(dumps(bct))

  >>> print template()
  <div>
    <div>
    <span>Hello, world!</span>
    </div>
  </div>

XML-support
-----------
  
  >>> print Template("""\
  ... <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  ... <div xmlns="http://www.w3.org/1999/xhtml">
  ...   Hello World!
  ... </div>""", mock_parser)()
  <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  <div xmlns="http://www.w3.org/1999/xhtml">
    Hello World!
  </div>  

Error handling
--------------

When an exception is raised during rendering, the exception is
augmented with information useful for debugging.

Note that the compiler must run in debug-mode to get this
functionality.

  >>> from chameleon.core import config
  >>> config.DEBUG_MODE = True

To test the error handler, we'll try to call a symbol `dummy`; for
technical reasons, we must wrap this in an encoded pickle---this is
due to our test setup.
  
  >>> from chameleon.core.types import value
  >>> from base64 import encodestring
  >>> from cPickle import dumps

  >>> template = Template("""\
  ... <div meta:replace="%s" />""" % encodestring(dumps(value('dummy()'))),
  ... mock_parser)

First, a simple example where a ``NameError`` exception is raised in a
function which we'll call from inside the template.
  
  >>> def dummy():
  ...     print i

  >>> print template(dummy=dummy)
  Traceback (most recent call last):
    ...
    print i
    ...
  RuntimeError: Caught exception rendering template.
    ...
    "dummy()"
    ...
  NameError: ...

Note that the exception is a copy of the original exception, with a
customized ``__str__`` method.

  >>> class CustomException(Exception):
  ...     def __init__(self, msg):
  ...         self.msg = msg
  
  >>> def dummy():
  ...     raise CustomException("This is a custom error message.")

  >>> try:
  ...    print template(dummy=dummy)
  ... except CustomException, exc:
  ...    print exc.msg
  This is a custom error message.

