ZPT

April 04, 2012

Using ZPT with Django

Zope.org - Django Page Templates

Posted by pj at 10:57 PM | Comments (0)

March 29, 2009

ZPT with CherryPy

ZPT - CherryPy Tools - Trac

svn co svn://svn.zope.org/repos/main/zpkgtools/trunk

Posted by pj at 12:05 AM | Comments (0)

August 08, 2006

Calling DTML from within ZPT

<tal:block 
    tal:define="header python:root.standard_html_header(context); 
    footer python:root.standard_html_footer(context)">
<tal:block tal:replace="structure header"/> 

....

<tal:block tal:replace="structure footer"/>
</tal:block>

Posted by pj at 11:55 AM | Comments (0)

April 21, 2005

Testing for the presence of objects in Zope

Here's a ZPT way to check for the presence of a particular folder in Zope:

<tal:block tal:define="
  folders python:context.objectValues('Folder');
" tal:repeat="folder python:folders">
<tal:block tal:define="
  this_id python:folder.getId();
  folder_name python:record['foaf_nick_name'];
" tal:condition="python:this_id == folder_name">
<tal:block tal:condition="python: root.new_site.contact.is_rstx_here(folder=folder,test_id='role_stx') == 1
">
<h3>Role and responsibilities</h3>
<tal:block tal:define="
  rstx python:modules['Products'].PythonScripts.standard.restructured_text;
  content_text python: folder.role_stx;
" tal:replace="structure python:rstx(content_text)"/>
</tal:block>
</tal:block>
</tal:block>

The following Python does the same but checks for rstx docs or DTML methods and is called as is_rstx_here() above:

for item in folder.objectValues('ReStructuredText Document'):
  this_id = item.getId()
  if this_id == str(test_id):
    return 1
for item in folder.objectValues('DTML Method'):
  this_id = item.getId()
  if this_id == str(test_id):
    return 1
return 0

Posted by pj at 04:31 PM

April 20, 2005

Contingent DIV blocks in ZPT - a design flaw.

I've got a problem with the design of ZPT. If I want a DIV block which starts in one iteration of a tal:repeat block but finishes a number of iterations later, then this can't be done, because the resulting code would give opening and closing tags out of document sequence breaking the template.

The only recourse seems to be to print the extra tagging as a a result of a tal:condition test.. YUUUCK:

<tal:block
tal:define="
global counter python:counter + 1;
global odd_even python:root.new_site.odd_or_even(test_figure=counter);
"
tal:condition="python: odd_even == 'odd'"
tal:replace="structure string:&lt;div class=&quot;row&quot;&gt;"/>

....Then the same for the closing block...

<tal:block tal:condition="python: odd_even == 'even'" tal:replace="structure string:&lt;/div&gt; <!-- End of row div -->"/>

Posted by pj at 04:13 PM

Changing the content type in page templates

<tal:block tal:define="
dummy python: container.REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml');
" tal:replace="structure string:&lt;?xml version=&quot;1.0&quot;?&gt;"/>

Posted by pj at 01:03 PM

April 18, 2005

Calling one page template inside another

Wow this is so much easier than calling DTML from within ZPT:

(In fact maybe you could do this with DTML too :~)

<tal:block tal:define="
dummy python: container.REQUEST.set('foaf_email', record['foaf_email']);
content_text root/new_site/contact/embedded_foafs;"
tal:replace="structure python: '<!--' + content_text + '-->'"/>

Note that I can pass it params in the REQUEST too..

Posted by pj at 03:48 PM

How to do RDF with Zope / ZPT

I've been trying to generate FOAF RDF from a Page Template. This has proven quite tricky. Zope 2.7 seems to stop wanting to parse and render the template if you change the content-type to text/xml from text/html.

This is not only a pain but is also intermittent.

The first thing I had to do therefore was re-set the content-type in the response header as follows, leaving the template content-type as text/html so the ZPT engine would parse it:

<tal:block tal:define="
dummy python: container.REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml');" />

Then I had to use tal:replace to put the XML declaration back in:

<tal:block tal:define="dummy python:
container.REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml');"
tal:replace="structure
string:&lt;?xml version=&quot;1.0&quot;?&gt;"/>

Because I wanted to use the same template for single FOAFs and multiples I had to test for a foaf_email parameter in the request. This is doable with has_key.

However, because tal:condition affects both subsequent tal:define statements and the rendering of any child nodes within the block where it is called, and scope of tal:define vars is limited to the current block, I've had to resort to passing variables up into the request namespace. This is due to the lack of a syntactic equivalent of <dtml-if>..<dtml-else>. This gives very obfuscatory code:

<tal:block tal:define="
request python: container.REQUEST;
email python: None;
where_clause string: where 1;
wc python: request.set('where_clause', where_clause);
">
<tal:block tal:condition="python:request.has_key('foaf_email')">
<tal:block tal:define="
email python: request['foaf_email'];
where_clause python:' where foaf_email=\'' + str(email) + '\'';
wc python: request.set('where_clause', where_clause);
"/>
</tal:block>
<rdf:RDF
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#"
xmlns:mofoaf="http://minnesota.ncl.ac.uk/mofoaf/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/"
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:dc="http://purl.org/dc/elements/1.1"
tal:define="
foaf_recs
python:root.generic_query(query_sql='select * from ltsn01_ng.01_foafs' + request['where_clause']);
work_url string:http://www.ltsn-01.ac.uk;
info_url_stem python: work_url + '/new_site/contact/person_details?foaf_id=';
">
.....RDF stuff here.....
</rdf:RDF>
</tal:block>

You'll see the where clause for the SQL is fished out of the request namespace.

The full template is here:

- 01_foafs.rdf.txt

Hmmm.. Seems if I'd read my own posts I could have done it with a PHP like global statement instead.


Posted by pj at 01:24 PM

December 15, 2004

Doozers in ZPT

I've been working on converting my DTML generic form builder into ZPT.

It has taken me a couple of days to move the concept of a doozer over. A doozer is a script which performs some business logic functions, such as inserting data into a table but instead of returning any resulting HTML, hands off to another URI using a redirect.

The main trick I was missing was the use of either tal:block or the tal:omit-tag="" attribute to ensure nothing is written to the browser before the redirect. I then discovered that this is actually unecessary as unlike PHP if you call a redirect it seems to send a new header to the browser anyway.

<div tal:define="
  debug python:0;
  table_name request/table_name;
  pk_recs python:here.get_pk_column(table_name=table_name);
  title_column python:str(pk_recs[0]['title_column']);
  pk_column python:str(pk_recs[0]['pk_column']);
  these_items python:request.form;
  title_column_value python:these_items[title_column];
  result python:here.insert_entry_id(table_name=table_name, title_column=title_column, this_value=title_column_value);
  max_id_recs python:here.get_table_max_id(table_name=table_name,pk_column=pk_column);
  entry_id python:max_id_recs[0]['entry_id'];" tal:omit-tag="">
<p tal:condition="python:debug == 1" tal:content="title_column" tal:omit-tag=""></p>
<p tal:condition="python:debug == 1" tal:content="title_column_value" tal:omit-tag=""></p>
<p tal:condition="python:debug == 1" tal:content="entry_id" tal:omit-tag=""></p>
<div tal:repeat="item_key python:these_items.keys()" tal:omit-tag="">

<p tal:define="item_value python:these_items[item_key];" tal:omit-tag="">

<span tal:condition="python:debug == 1" tal:omit-tag="">
<span tal:condition="python:debug == 1" tal:content="item_key" tal:omit-tag=""></span>
<span tal:condition="python:debug == 1" tal:content="item_value | nothing" tal:omit-tag="">Item here<
/span>
</span>

<span tal:condition="python:item_key != 'table_name' and item_key != 'redirect_url'" tal:omit-tag="">
<br
  tal:define="result python:here.update_entry(table_name=table_name,pk_column=pk_column,
this_key=item_key,this_value=item_value,entry_id=entry_id)"
  tal:omit-tag=""/>
</span>
</p>
</div>
<p tal:condition="python:debug == 1" tal:content="these_items" tal:omit-tag=""></p>
<div tal:condition="python:not request.has_key('redirect_url')" tal:omit-tag="">
<br tal:omit-tag="" tal:define="
  redirect_url python:'/generic_form_zpt/show_entry?entry_id=' + str(entry_id) 
+ '&table_name=' + table_name + '&pk_column=' + pk_column 
+ '&title_column=' + title_column;
  redirect python:request.RESPONSE.redirect(redirect_url);
"/>
</div>
<div tal:condition="python:request.has_key('redirect_url')" tal:omit-tag="">
<br tal:omit-tag="" tal:define="
  final_url python:request['redirect_url'] + '?entry_id=' + str(entry_id) 
+ '&table_name=' + table_name + '&pk_column=' + pk_column + '&title_column=' 
+ title_column;
  redirect python:request.RESPONSE.redirect(final_url);
"/>
</div>
</div>

Posted by pj at 04:01 PM

December 13, 2004

Overriding angle bracket escaping in ZPT

To avoid ZPT turning your HTML angle brackets into entity codes prefix your tal:replace statement with the structure keyword.

<span tal:replace="structure my_value"/>

Posted by pj at 05:56 PM

December 03, 2004

Wish I'd found this a few days ago

Zope.org - DTML2ZPT Conversion examples

Posted by pj at 08:55 AM

December 02, 2004

This is quite sick - ZPT in PHP

circle.ch :: PHPTAL - PHP Template Attribute Language

http://phptal.sourceforge.net/

Posted by pj at 09:36 PM

November 26, 2004

Figured out where I was going wrong..

Note to self..

I need to use macros in my ZPT form builder. That's where I was going wrong.

Posted by pj at 08:38 PM

November 25, 2004

How to call REQUEST.set() from within ZPT

 > How do I call REQUEST.set() ?
Most uses of "REQUEST.set" can be avoided in ZPT because it has
true assignment:

     tal:define="var value;
                 global global_var  value;
		 ...
		"

If you need to communicate with objects outside the ZPT (and you
want to use "REQUEST" for this), you can use

     tal:define="dummy python: request.set(....)"

http://mail.zope.org/pipermail/zpt/2002-January/002763.html

Posted by pj at 05:09 PM