You are not logged in Log in Join
You are here: Home » Members » peterbe » DTML2ZPT Conversion examples

Log in
Name

Password

 

"Your examples just crystalized in my brain and caused me to grasp
some concepts about ZPT that have been driving me nutz!"

- Matthew Stott

"Anyway, thanks again for a great page.
It helped me get started with ZPT and now I'm hooked!"

- Paul Winkler

So I've been experimenting a bit with ZPT (Zope Page Templates).
It uses something called TAL instead of DTML code to do some business logic in the templates. To learn this I thought it would be useful to understand/learn TAL using by knowledge in DTML.
I also hope very much that this will help others like me.

Email [email protected] about changes/additions please.
Or visit my website on www.peterbe.com



Using nocall (example1)
DTML
<dtml-with "subfolder.index_html">
  <a href="<dtml-var absolute_url>" title="<dtml-var title>"><dtml-var title></a>
</dtml-with>
ZPT
<a href="dummylink.html" title="Dynamic Title"
  tal:define="doc nocall:context/subfolder/index_html;title doc/title"
  tal:attributes="href doc/absolute_url; title title"
  tal:content="title">Dynamic Title</a>

Variant path (example10)
DTML
<H1><dtml-var "subfolder[strid].title"></H1>
ZPT
<H1 tal:content="python:path('context/subfolder/%s/title' % strid)">
Varying Title</H1>

url_quote (example11)
DTML
<dtml-var "'?a=b'" url_quote>
ZPT
<span tal:define="pss modules/Products/PythonScripts/standard"
tal:replace="python:pss.url_quote('?a=b')"></span>



(nb. extract from Products.PythonScripts.standard: from DocumentTemplate.DT_Var import special_formats, \ whole_dollars, dollars_and_cents, structured_text, sql_quote, \ html_quote, url_quote, url_quote_plus, newline_to_br, thousands_commas

DTML
context.manage_addDTMLMethod('id',title='Title',file='<dtml-var username>')
ZPT
context.manage_addZopePageTemplate('id')
context['id'].pt_setTitle('Title')
context['id'].write('<div tal:replace="context/username" />')

DTML
<textarea name="users:list"
><dtml-in "getUsers()"><dtml-var sequence-item><dtml-unless sequence-end> </dtml-unless></dtml-in></textarea>
ZPT
<textarea name="users:list" 
    tal:define="users context/getUsers | nothing; string modules/string" 
    tal:content="python:string.join(users or [],'\n')"></textarea>

DTML
<dtml-unless "REQUEST.has_key('usernames')">
    <dtml-call "REQUEST.set('usernames',[])">
</dtml-unless>
<select name="usernames:list">
<dtml-in usernames>
    <option <dtml-if "_['sequence-item'] in REQUEST['usernames']">selected</dtml-if>
    ><dtml-var sequence-item></option>
</dtml-in>
</select>
ZPT
<select name="usernames:list" tal:define="emptylist python:[];
                                          usernames python:context.getUsernames();
                                          selectedones request/usernames | emptylist">
 	<option tal:repeat="username usernames"
                tal:attributes="selected python:username in selectedones"
                tal:content="python:username">displayname</option>

</select>

DTML
<dtml-var image1>
ZPT
<div tal:replace="structure container/image1">image goes here</div>

<img tal:replace="structure container/image1" alt="image goes here" src="dummy.jpg" />

DTML
<dtml-let i2="_['image2.jpg'].absolute_url()">
  <a href="&dtml-i2;">Image2.jpg</a>
</dtml-let>
ZPT
<a href="" 
  tal:attributes="href container/image2.jpg/absolute_url">
Image2.jpg
</a>


cheers Paul Winkler for this one!

DTML
<ul>
    <dtml-in "objectValues(['Link', 'Favorite'])" skip_unauthorized>
        <li><dtml-var sequence-item></li>
    </dtml-in>
</ul>
ZPT
<ul tal:define="ztu modules/ZTUtils;
                objs python:context.objectValues(['Link', 'Favorite']);
                authobjs python:ztu.LazyFilter(objs, skip='')">
<li tal:repeat="obj authobjs"></li>

DTML
<dtml-var something html_quote>
ZPT
<span tal:replace="template/something | container/something | options/something | 
                   root/something | request/something"/>

DTML
:: in object standard_html_header ::

<dtml-if "determineStyle()=='simple'">
    <dtml-var standard_html_header_simple>
<dtml-else>
    <dtml-var standard_html_header_default>
</dtml-if>
ZPT
:: in object index_html ::

<html metal:use-macro="context/getStyle">

:: in object getStyle (Python Script) ::

if context.determineStyle()=='simple':
    return context.standard_master_simple.macros['standard']
else:
    return context.standard_master_default.macros['standard']


----
Note that the Page Template objects 'standard_master_simple'
and 'standard_master_default' both start like this: <html metal:define-macro="standard">

DTML
<H4>
<dtml-if "_.len(result)==0">
  <dtml-var document_title>
<dtml-else>
  Untitled
</dtml-if>
</H4>
ZPT
<H4>
  <span tal:replace="template/title" 
        tal:condition="python:len(result)==0"/>
  <span tal:replace="string:Untitled"
        tal:condition="python:not(len(result)==0)"/>
</H4>

or

<h4 tal:content="python:test(len(result)==0, default,
path('template/title'))">Untitled</h4>

DTML
<dtml-in somesequence>
  <li><dtml-var sequence-item>
  <dtml-unless sequence-end>
    <br>
  </dtml-unless>
</dtml-in>
ZPT
<span tal:repeat="item context/somesequence">
  <li tal:content="item"></li>
  <br tal:condition="not:repeat/item/end"/>
</span>

---
See further RepeatVariable

DTML
<p>
<dtml-try>
 My name is <dtml-var SlimShady>
<dtml-except>
  Noops. No slim
</dtml-try>
</p>
ZPT
<p tal:on-error="string: Noops. No slim">
My name is <span tal:replace="context/SlimShady" />.
</p>

Batch looping (example4)
DTML
<dtml-if "REQUEST.has_key('b_start')">
  <dtml-call "REQUEST.set('b_start',_.int(b_start))">
<dtml-else>
  <dtml-call "REQUEST.set('b_start',0)">
</dtml-if>
<dtml-call "REQUEST.set('size', 3)">
<dtml-call "REQUEST.set('foods',['sandwiches', 'pie', 'meatloaf', 
                                         'berries', 'bread', 'coffee', 
                                         'some', 'thing', 'else'])">

<a href="?b_start=<dtml-var "b_start-size">">Previous <dtml-var size></a>
<dtml-in foods size=size orphan=1 start=b_start>


  <p>
  <dtml-var sequence-item>
  </p>

</dtml-in>
<a href="?b_start=<dtml-var "b_start+size">">Next <dtml-var size></a>
ZPT
<div tal:define="b_start python:path('request/b_start') or 0;
                 results python:context.listProducts(popular=0);
                 Batch python:modules['ZTUtils'].Batch;
                 global batch python:Batch(results, 5, int(b_start),
orphan=1)"
     tal:replace="nothing" />

    <a href="nextbatch" tal:define="p batch/previous"
       tal:condition="p"
       tal:attributes="href string:?b_start=${p/first}">
       Previous <span tal:replace="p/length">n</span>
    </a>

    <p tal:repeat="food batch">
        <span tal:replace="food">food</span>, 
    </p>


    <a href="nextbatch" tal:define="n batch/next"
       tal:condition="n"
       tal:attributes="href string:?b_start=${batch/end}">
       Next <span tal:replace="n/length">n</span>
    </a>

DTML
<a href="mailto:<dtml-var webmaster>?subject=<dtml-var document_title>">
      Email webmaster</a>
ZPT
<a tal:attributes="href string:mailto:${context/webmaster}?subject=${template/title}"
      href=""
      >Email webmaster</a>

Path modifiers (example6)
DTML
<dtml-var knife missing>
<dtml-var fork  missing="Bring one next time will ya">
<dtml-var spoon null="At least it's an empty spoon">
ZPT
<span tal:replace="knife | nothing" />
<span tal:replace="fork | default">Bring one next time will ya</span>
<span tal:replace="python:spoon or default">At least it's an empty
spoon</span>

DTML
<ul>
<dtml-in "mydb.selectbyname(name='peter')">
  <li><dtml-var surname>
</dtml-in>
</ul>
ZPT
<ul tal:define="sequence python:container.mydb.selectbyname(name='peter')">
  <li tal:repeat="item sequence">
  <span tal:replace="item/surname">surname</span></li>
</ul>

REQUEST info (example8)
DTML
<dtml-var REQUEST>
ZPT
<span tal:replace="structure request">info about the request namespace</span>

DTML
<p>
<dtml-var document_title>
<dtml-var title>
</p>
ZPT
<p>
<span tal:replace="python:path('template/title')">python:path('template/title')</span>
<span tal:replace="python:path('context/title')">python:path('context/title')</span>
</p>
[or]
<p>
<span tal:replace="python:template.title">python:template.title</span>
<span tal:replace="python:context.title">python:context.title</span>
</p>