« March 2005 | Main | May 2005 »
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:<div class="row">"/>
....Then the same for the closing block...
<tal:block tal:condition="python: odd_even == 'even'" tal:replace="structure string:</div> <!-- 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:<?xml version="1.0"?>"/>
Posted by pj at 01:03 PM
Testing counters to see if they are odd or even
The following is a simple Python script to test whether a number is odd or even:
test_figure = float(test_figure) half_of_it = float(test_figure/2) #print str(half_of_it) if int(half_of_it) == float(half_of_it): return 'even' else: return 'odd'
It relies on the fact that casting a floating point number to an integer will round it up or down, and that dividing an odd number by two always gives a float, whereas dividing an even number gives an integer.
Posted by pj at 11:14 AM
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:<?xml version="1.0"?>"/>
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:
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
April 15, 2005
New 'Back in Business' FOAF specification
Posted by pj at 11:24 AM
April 13, 2005
Identifying unique visitors to a website
A list and explanation of the ways Urchin software uses to determine unique visits. The only way to avoid proxy and cache issues is to use their bespoke JavaScript tracking approach:
Urchin Documentation - Visitor Identification Methods
Posted by pj at 08:40 PM
Merging multiple RSS feeds
Suzanne thought it would be a good idea if we could merge multiple news feeds from BIOME, HS&P and HEALTH-01 for our joint portal page.
Whilst unconvinced of the requirement for such a thing I have come up with the following:
- http://www.ltsn-01.ac.uk/static/merge_feeds.php
To get a text/xml
view of it in your browser use:
- http://www.ltsn-01.ac.uk/static/merge_feeds.php?debug=1
The script is as follows:
- http://www.ltsn-01.ac.uk/static/merge_feeds.txt
Merging multiple RSS feeds into one involves de-duping based on link URLs in items and interleaving items so that they appear next to items of the same age in the final feed.
The script pulls our news feed and the feed from a blog we're hosting and represents them. In theory it can handle as many feeds as you want.
But why? I hear you ask.. Errm.. still not sure? Suzanne?
As a side effect of all this work, I was determined to get the feed to validate on http://feedvalidator.org.
It doesn't like my image references so those are gone from the feed, then it was a matter of getting the right content-type (application/rss+xml
), stripping annoying Windows meta characters from the feed, making sure there are no duplicate URLs, and I've UTF-8 encoded the final output for good measure.
- http://www.ltsn-01.ac.uk/static/strip_ms_chars.txt
Basically all the problems we've had with the LOM XML stuff.
I've done this with the rest of our feeds too and they now validate.
Posted by pj at 04:58 PM
April 12, 2005
Why 1.0 is best..
Posted by pj at 08:44 AM
Handling RSS 1.0 in PHP
Posted by pj at 08:43 AM
April 11, 2005
RSS events to XHTML notes by Libby Miller
Posted by pj at 03:05 PM
April 09, 2005
Embedding RDF in XHTML the hard way
Posted by pj at 05:27 PM
April 08, 2005
Meatspace metadata and authentication reminiscences
Super Springtime Dogtag Dignity contest results
Thanks for highlighting my lack of legal training Dr. P..
Posted by pj at 11:51 PM
A Python RDF parser
rdfxml.py: An RDF/XML Parser in under 10KB of Python
Posted by pj at 04:50 PM
The cult of Tony
We want a Labour party on May 6th. We just aren't inviting Tony:
Backing Blair :: UK General Election 2005
Take part in Operation Henman..
Print out a poster:
Posted by pj at 10:58 AM
April 07, 2005
Article about the UK Creative Commons effort
Policy DevCenter: Some Rights Reserved
Posted by pj at 07:50 PM
Doing dynamic reStructuredText in Zope
Suzanne and I have been playing with reStructuredText in Zope as a means of rapidly adding large chunks of copy to our new website. It is HWAYYY better than the old StructuredText.
The policy on the new site is that we are more carefully managing the URLs in page links and for the moment at least storing these as folder properties to be called in ZPT. This means for the navigation we only need to change URLs in one place.
We need to able to do the same in a simple way for links in rstx. This has its own way of handling URLs for links where they need only be defined once in the document to be re-used in lots of places.
We need a way to insert the values of properties into our rstx documents.
Fortunately in ZPT (which is where we are calling our rstx from) you have to define a rstx parser object and then pass text to it. This means that we could pass it the result of a DTML method and have the template still treat that text as rstx.
So instead of creating a reStructuredText document with the following:
.. _contact_us: /contact/contact_us
We create a DTML method with the following:
.. _contact_us: <dtml-with new_site><dtml-var contact_us_url></dtml-with>
So in our page template we now have the following to call the stx engine and the dtml:
<div style="text-align: justify;" id="content" tal:define="stx python:modules['Products'].PythonScripts.standard.restructured_text; content_text python:root.contact.index_html_dtml(root.contact);" tal:content="structure python:stx(content_text)"/>
Where this syntax: python:root.contact.index_html_dtml(root.contact)
calls the DTML, passing its context as an argument.
Posted by pj at 11:12 AM
April 04, 2005
Paper detailing how to rig Zope / Plone up with Shibboleth authentication
Posted by pj at 08:56 PM
April 03, 2005
Datamining Apache Logs with PostgreSQL
ONLamp.com: Datamining Apache Logs with PostgreSQL
Datamining Apache Logs with PostgreSQL
Posted by pj at 09:15 PM