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

This test demonstrates the compilation of TAL and METAL attribute
languages.

TAL
---
  
:: Namespace elements

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

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

tal:attributes 'checked' and 'selected' toggles

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <option tal:attributes="selected True"></option>
  ...   <option tal:attributes="selected None"></option>
  ...   <input tal:attributes="checked True" />
  ...   <input tal:attributes="checked False" />
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
     <option selected="True"></option>
     <option></option>
     <input checked="True" />
     <input />
  </div>

tal:repeat
    
  >>> print render("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
    <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("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
      <ul>
        <li>0 True</li>
        <li>1 False</li>
        <li>2 True</li>
      </ul>
    </div>

tal:condition

  >>> print render("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
      <div>
        Show me!
      </div>
    </div>

:: TAL elements with namespace prefix

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <tal:example replace="'Hello World!'" />
  ...   <tal:example tal: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 xmlns="http://www.w3.org/1999/xhtml">
      Hello World!
      Hello World!
      Hello World!
      0
      1
      2
      True
    </div>

tal:omit-tag

  >>> print render("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
      No paragraph here.
      No paragraph here either.
      <p>A paragraph here.</p>
    </div>

:: Unicode with dynamic attributes and content
    
  >>> print render("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
      <img title="&lt;Hello&gt;" />
      <br />
      &lt;br /&gt;
      <span>La Peña</span>
    </div>

:: Using the "string:" expression

  >>> print render("""\
  ... <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 xmlns="http://www.w3.org/1999/xhtml">
    Hello, world!
    <img alt="Leonardo da Vinci; Musee du Louvre, 1503" title="Mona Lisa" />
  </div>

:: Using different expressions with try-except operator (|)
  
  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...      <span tal:replace="abc|1" />
  ...      <span tal:replace="2|abc" />
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
       1
       2
  </div>

:: Using the "structure" TAL pragma.

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <span tal:replace="structure dir" />
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
    <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, <span tal:replace="name|string:earth" />!
  ...   </div>
  ...   <div tal:define="name 'world'">
  ...     <div metal:use-macro="template.macros['greeting']" />
  ...   </div>  
  ... </div>"""

  >>> from chameleon.core.testing import MockTemplate
  >>> from chameleon.zpt.language import Parser

  >>> template = MockTemplate(body, Parser())
  >>> print render(body, template=template)
  <div xmlns="http://www.w3.org/1999/xhtml">
    <div class="greeting">
      Hello, earth!
    </div>
    <div>
      <div class="greeting">
      Hello, world!
    </div>
  <BLANKLINE>
    </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">
  ...     Hey, <span class="name" metal:define-slot="name">
  ...     a <em>stranger!</em></span>
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     This will be omitted
  ...     <span metal:fill-slot="name">earth!</span>
  ...   </div>
  ...   <div metal:use-macro="template.macros['greeting']">
  ...     <div>
  ...       <metal:earth fill-slot="name">earth!</metal:earth>
  ...     </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>"""

  >>> template = MockTemplate(body, Parser())
  >>> print render(body, template=template)
  <div xmlns="http://www.w3.org/1999/xhtml">
    <div>
      Hey, <span class="name">
      a <em>stranger!</em></span>
    </div>
    <div>
      Hey, <span class="name">earth!</span>
    </div>
  <BLANKLINE>
    <div>
      Hey, <span class="name">earth!</span>
    </div>
  <BLANKLINE>
    <div>
      Hey, <span class="name">
      a <em>stranger!</em></span>
    </div>
  <BLANKLINE>
    <div>
      Hey, <span class="name">
      a <em>stranger!</em></span>
    </div>
  <BLANKLINE>
  </div>

Expression interpolation
------------------------

The ``chameleon.zpt`` parser supports Genshi interpolation
expressions.

Outside tags:

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   Interpolation ${'expressions'} are ${'convenient'}.
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
    Interpolation expressions are convenient.
  </div>

Inside tags:

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal">
  ...   <img alt="Interpolation ${'expressions'} are ${'convenient'}" />
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
    <img alt="Interpolation expressions are convenient" />
  </div>

We can disable this feature using ``meta:interpolation``::

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:tal="http://xml.zope.org/namespaces/tal"
  ...      xmlns:meta="http://xml.zope.org/namespaces/meta">
  ...   <div meta:interpolation="false">
  ...     ${'foo'}
  ...   </div>
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
    <div>
      ${'foo'}
    </div>
  </div>

The ``tail`` of an element does get intepolated depending oon
it's parent::

  >>> print render("""\
  ... <div xmlns="http://www.w3.org/1999/xhtml"
  ...      xmlns:meta="http://xml.zope.org/namespaces/meta">
  ...   <div meta:interpolation="false">
  ...     ${nope}
  ...   </div>
  ...   ${'interpolation'}
  ...   <div>
  ...     ${'interpolation'}
  ...     <span meta:interpolation="false">
  ...       ${nope}
  ...       <span meta:interpolation="true">
  ...         ${'interpolation'}
  ...       </span>
  ...       ${'nope'}
  ...     </span>
  ...   </div>
  ... </div>""")
  <div xmlns="http://www.w3.org/1999/xhtml">
    <div>
      ${nope}
    </div>
    interpolation
    <div>
      interpolation
      <span>
        ${nope}
        <span>
          interpolation
        </span>
        ${'nope'}
      </span>
    </div>
  </div>

