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

This section demonstrates the high-level template classes.

z3c.pt.pagetemplate.PageTemplate
--------------------------------

  >>> from z3c.pt import PageTemplate
  >>> from z3c.pt.testing import MockParser
  
  >>> print PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml">
  ...   Hello World!
  ... </div>""")()
  <div>
    Hello World!
  </div>

z3c.pt.pagetemplate.PageTemplateFile
------------------------------------

  >>> from z3c.pt import PageTemplateFile
  >>> from z3c.pt 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

z3c.pt.pagetemplate.ViewPageTemplate
------------------------------------

  >>> from z3c.pt import ViewPageTemplate
  
  >>> class ViewPageTemplateView(object):
  ...     __call__ = ViewPageTemplate(
  ...          open(path+'/view.pt').read())
  ...     request = u'request'
  ...     context = u'context'

  >>> view = ViewPageTemplateView()
    
  >>> print view(test=u'test')
  <div>
    <span>&lt;ViewPageTemplateView object at ...&gt;</span>
    <span>context</span>
    <span>request</span>
    <span>test</span>
  </div>

z3c.pt.pagetemplate.ViewPageTemplateFile
----------------------------------------

  >>> from z3c.pt import ViewPageTemplateFile
  
  >>> class ViewPageTemplateView(object):
  ...     __call__ = ViewPageTemplateFile(path+'/view.pt')
  ...     request = u'request'
  ...     context = u'context'

  >>> view = ViewPageTemplateView()

  >>> print view(test=u'test')
  <div>
    <span>&lt;ViewPageTemplateView object at ...&gt;</span>
    <span>context</span>
    <span>request</span>
    <span>test</span>
  </div>

z3c.pt.texttemplate.ViewTextTemplate
------------------------------------

  >>> from z3c.pt import ViewTextTemplate
  
  >>> class ViewTextTemplateView(object):
  ...     __call__ = ViewTextTemplate(open(path+'/view.css').read())
  ...     request = u'request'
  ...     context = u'context'

  >>> view = ViewTextTemplateView()

  >>> print view(color=u'#ccc')
  #region {
      background: #ccc;
  }

z3c.pt.texttemplate.ViewTextTemplateFile
----------------------------------------

  >>> from z3c.pt import ViewTextTemplateFile
  
  >>> class ViewTextTemplateView(object):
  ...     __call__ = ViewTextTemplateFile(path+'/view.css')
  ...     request = u'request'
  ...     context = u'context'

  >>> view = ViewTextTemplateView()

  >>> print view(color=u'#ccc')
  #region {
      background: #ccc;
  }

Compiler integration
--------------------

Certain constructs require close collaboration between the template
compiler and the page template classes.

py:match integration

  >>> from z3c.pt.genshi import GenshiParser
  
  >>> print PageTemplate("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:py="http://genshi.edgewall.org/">
  ...   <py:match path="xmlns:greeting">Hello ${select('@name')[0]}!</py:match>
  ...   <greeting name="World" />
  ... </div>
  ... """, parser=GenshiParser)()
  <div>
    Hello World!
  <BLANKLINE>
  </div>

metal:define-macro, metal:use-macro

  >>> template1 = 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">
  ...   <div metal:define-macro="greeting">
  ...     Hello, ${name}!
  ...     <span tal:define="global name 'earth'">
  ...       Hello, ${name}!
  ...     </span>
  ...     Hello, ${name}!
  ...   </div>
  ... </div>""")

  >>> template2 = 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">
  ...   <div tal:define="name 'world'">
  ...     <div metal:use-macro="template1.macros['greeting']" />
  ...     Hello, ${name}!
  ...   </div>
  ...   Hello, ${name}!
  ... </div>""")

  >>> print template2(template1=template1)
  <div>
    <div>
      <div>
      Hello, world!
      <span>
        Hello, earth!
      </span>
      Hello, earth!
    </div>
  <BLANKLINE>
      Hello, world!
    </div>
    Hello, earth!
  </div>

metal:define-macro, metal:use-macro, metal:define-slot, metal:fill-slot

  >>> 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>

xi:include

  >>> from z3c.pt.template import BaseTemplateFile
  >>> template = BaseTemplateFile(path+"/xinclude1.pt", MockParser)
  >>> print template()
  <div>
    <div>
    <span>Hello, world!</span>
    </div>
  </div>

:: XInclude in Genshi

When using XInclude-statements in Genshi, macro-definitions are
carried over from the included template. This is demonstrated below.

  >>> template = BaseTemplateFile(path+"/xinclude3.pt", GenshiParser)
  >>> print template()
  <div>
  <BLANKLINE>
  <BLANKLINE>
    <p class="greeting">
      Hello, world!
    </p>
  <BLANKLINE>
  </div>
  
  
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:

  >>> from z3c.pt import PageTemplate
  >>> 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):
    ...
  TypeError: range expected at least 1 arguments, got 0

Exception while evaluating definition:

  >>> from z3c.pt import PageTemplate
  >>> 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):
    ...
  TypeError: range expected at least 1 arguments, got 0

Exception while evaluating interpolation:

  >>> from z3c.pt import PageTemplate
  >>> 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):
    ...
  TypeError: range expected at least 1 arguments, got 0
