Zope Page Templates (ZPT)
=========================

  >>> from z3c.pt.testing import render_zpt

TAL
---
  
:: Namespace elements

  >>> print render_zpt("""\
  ... <tal:block xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   Hello, world!
  ... </tal:block>""")
  <BLANKLINE>
    Hello, world!
  <BLANKLINE>

tal:define, tal:attributes, tal:contents    
  
  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span id="test"
  ...         class="dummy"
  ...         tal:define="a 'abc'"
  ...         tal:attributes="class 'def' + a; style 'hij'"
  ...         tal:content="a + 'ghi'" />
  ...   <span tal:replace="'Hello World!'">Hello Universe!</span>
  ...   <span tal:replace="'Hello World!'"><b>Hello Universe!</b></span>
  ...   <span tal:content="None" />
  ... </div>""")
    <div>
      <span id="test" style="hij" class="defabc">abcghi</span>
      Hello World!
      Hello World!
      <span></span>
    </div>

tal:repeat
    
  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <ul>
  ...     <li tal:repeat="i range(5)"><span tal:replace="'Item ' + str(i) + ')'" /></li>
  ...   </ul>
  ... </div>""")
    <div>
      <ul>
        <li>Item 0)</li>
        <li>Item 1)</li>
        <li>Item 2)</li>
        <li>Item 3)</li>
        <li>Item 4)</li>
      </ul>
    </div>

tal:repeat (repeat-variable)

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <ul>
  ...     <li tal:repeat="i range(3)"><span tal:replace="str(i) + ' ' + str(repeat['i'].even())" /></li>
  ...   </ul>
  ... </div>""")
    <div>
      <ul>
        <li>0 True</li>
        <li>1 False</li>
        <li>2 True</li>
      </ul>
    </div>

tal:condition

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <div tal:condition="True">
  ...     Show me!
  ...   </div>
  ...   <div tal:condition="False">
  ...     Do not show me!
  ...   </div>
  ... </div>""")
    <div>
      <div>
        Show me!
      </div>
    </div>

:: HTML comments

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <!-- a comment -->
  ...   <!-- a multi-
  ...        line comment -->
  ...   <!-- a comment with an ${'expression'} -->
  ... </div>""")
    <div>
      <!-- a comment -->
      <!-- a multi-
           line comment -->
      <!-- a comment with an expression -->
    </div>

:: TAL elements with namespace prefix

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <tal:example replace="'Hello World!'" />
  ...   <tal:div content="'Hello World!'" />
  ...   <tal:multiple repeat="i range(3)" replace="i" />
  ...   <tal:div condition="True">True</tal:div>
  ... </div>""")
    <div>
      Hello World!
      Hello World!
      0
      1
      2
      True
    </div>

tal:omit-tag

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <p tal:omit-tag="">No paragraph here.</p>
  ...   <p tal:omit-tag="True">No paragraph here either.</p>
  ...   <p tal:omit-tag="False">A paragraph here.</p>
  ... </div>""")
    <div>
      No paragraph here.
      No paragraph here either.
      <p>A paragraph here.</p>
    </div>

:: Unicode with dynamic attributes and content
    
  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <img tal:attributes="title '%sHello%s' % (chr(60), chr(62))" />
  ...   <span tal:replace="structure '%sbr /%s' % (chr(60), chr(62))" />
  ...   <span tal:replace="'%sbr /%s' % (chr(60), chr(62))" />
  ...   <span tal:content="unicode('La Pe\xc3\xb1a', 'utf-8')" />
  ... </div>""")
    <div>
      <img title="&lt;Hello&gt;" />
      <br />
      &lt;br /&gt;
      <span>La Peña</span>
    </div>

:: Using the "path:" expression

  >>> class Test(object):
  ...     greeting = u'Hello'
  
  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:replace="path: test1/greeting" />
  ...   <span tal:replace="path: test2/greeting" />
  ... </div>""", request=object(),
  ... test1={'greeting': u'Hello'}, test2=Test())
  <div>
    Hello
    Hello
  </div>

:: Using the "string:" expression

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:replace="string:${greeting}, world!" />
  ...   <img tal:attributes="alt string:Leonardo da Vinci;; Musee du Louvre, 1503;
  ...                        title string:Mona Lisa" />
  ... </div>""", request=object(), greeting=u'Hello')
  <div>
    Hello, world!
    <img alt="Leonardo da Vinci; Musee du Louvre, 1503" title="Mona Lisa" />
  </div>

:: Setting the default expression

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <div tal:default-expression="path">
  ...     <span tal:replace="test/greeting" />
  ...   </div>
  ... </div>""", request=object(), test={'greeting': u'Hello'})
  <div>
    <div>
      Hello
    </div>
  </div>

:: Using different expressions with try-except operator (|)
  
  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <tal:path-expression-testing 
  ...         define="request object();
  ...                 mydict {'a': 1, 'c': {'a': 2}}">
  ...       <div tal:default-expression="path">
  ...          <span tal:replace="mydict/a" />
  ...          <span tal:replace="mydict/b|mydict/a" />
  ...          <span tal:replace="mydict/c/a" />
  ...          <span tal:replace="python: 5+5" />
  ...       </div>
  ...       <span tal:replace="path: mydict/a" />
  ...       <span tal:replace="python: 1+1" />
  ...       <span tal:replace="path: mydict/b|True" />
  ...       <span tal:replace="int('a')|path: mydict/a" />
  ...   </tal:path-expression-testing>
  ... </div>""")
  <div>
  <BLANKLINE>
        <div>
           1
           1
           2
           10
        </div>
        1
        2
        True
        1
  <BLANKLINE>
  </div>

:: Using TAL pragmas "nocall" and "structure"

  >>> print render_zpt("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:default-expression="path"
  ...         tal:replace="structure nocall: dir" />
  ...   <span tal:replace="structure dir" />
  ... </div>""", request=object())
    <div>
      <built-in function dir>
      <built-in function dir>
    </div>

METAL
-----

metal:define-macro, metal:use-macro

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

  >>> from z3c.pt.testing import MockTemplate
  >>> from z3c.pt.zpt import ZopePageTemplateParser

  >>> template = MockTemplate(body, ZopePageTemplateParser)
  >>> print render_zpt(body, template=template)
  <div>
    <div>
      <div class="greeting">
        Hello, world!
      </div>
    </div>  
  </div>

metal:define-slot, metal:fill-slot

  >>> body = """\
  ... <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, <b class="name" metal:define-slot="name">stranger!</b>
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     <span metal:fill-slot="name">earth!</span>
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     <div>
  ...       <span metal:fill-slot="name">earth!</span>
  ...     </div>
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     <!-- display fallback greeting -->
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     <span metal:fill-slot="dummy">dummy!</span>
  ...   </div>
  ... </div>"""

  >>> from z3c.pt.testing import MockTemplate
  
  >>> template = MockTemplate(body, ZopePageTemplateParser)
  >>> print render_zpt(body, template=template)
  <div>
  <BLANKLINE>
      <div>
      Hello, <b class="name">earth!</b>
    </div>
  <BLANKLINE>
  <BLANKLINE>
      <div>
      Hello, <b class="name">earth!</b>
    </div>
  <BLANKLINE>
  <BLANKLINE>
      <div>
      Hello, <b class="name">stranger!</b>
    </div>
  <BLANKLINE>
  <BLANKLINE>
      <div>
      Hello, <b class="name">stranger!</b>
    </div>
  <BLANKLINE>
  </div>


