ScriptperlPod
NAME
zope-method - Writing Zope methods in various languages
DESCRIPTION
The purpose of this document is to give examples of more-or-less interesting Zope methods and show how the same method would look if it was implemented in DTML, Python or Perl. The main purpose is to document the mapping between languages, so that when you read documentation that use some specific language for its examples, you can easily map it to your preferred implementation language.
These examples should also serve as background information for discussions on improving the Zope Perl support, so that perl methods can be written without too much knowledge about the fact that Zope is implemented in Python underneath.
EXAMPLE 1
In the first example we have a method that list the content of the folder ``f1''. The DTML method code looks like this:
<dtml-in "f1.objectValues()"> <dtml-var id>: <dtml-var sequence-item> </dtml-in> done
The same as a Python method would look like this:
Param: self
for item in self["f1"].objectValues(): print item.id(), ": ", item print "done" return printed
The same as a Perl method would look like this:
Param: self
my @res; for ($self->{f1}->objectValues) { push(@res, join(": ", $->id, $)); } join("\n", @res, "done");
Alternative Perl method that does not use the easy way to access attributes or calling methods, but always use full API calls.
Param: self
use Python qw(getitem getattr funcall len str);
my @res; my $list = funcall(getattr(getitem($self, "f1"), "objectValues"));
for my $i (0 .. len($list) - 1) { my $item = getitem($i); push(@res, join(": ", funcall(getattr($item, id")), str($item))); } join("\n", @res, "done");
Discussion
The <dtml-in> construct is the same as a for-loop in both python and perl. Otherwise the code should be easy enough to read.
For python methods there is some magic going on with printing and the
variable printed
. This can be replicated for perl with the use of
tied file handles. I am not sure it is a good idea yet.
EXAMPLE 2
The ``Elvis Lives'' tutorial lesson 8 has an example of scripts managing image uploads from a form that looks like this:
<h2><dtml-var title></h2>
<p>Upload a picture to the Elvis Photo Archive.</p>
<form action="photoAction" method="post" enctype="multipart/form-data"> <p>Title: <input type="text" name="photo_title"></p> <p>File: <input type="file" name="file"></p> <input type="submit"> </form>
<dtml-var standard_html_footer>
The DTML method to handle upload submissions look like this:
<dtml-var standard_html_header> <h2><dtml-var title></h2>
<dtml-call expr="photoArchive.manage_addImage( id='', file=file, title=photo_title)">
<p>Thanks for your photo submission.</p> <dtml-var standard_html_footer>
The same as a python method could look like this:
Param: self, file, photo_title
print self.standard_html_header(self) print "<h2>" + self.title + "</h2>"
self["photoArchive"].manage_addImage( id='', file=file, title=photo_title)
print "<p>Thanks for your photo submission.</p>" print self.standard_html_footer(self)
return printed
The same as a perl method would look like this:
my @res; push(@res, $self->standard_html_header($self));
push(@res, "<h2>", $self->title, "</h2>");
$self->{f1}->manage_addImage(id => "", file => $file, *title => $photo_title);
push(@res, "<p>Thanks for your photo submission.</p>");
push(@res, $self->standard_html_footer($self)); join("", @res);
Discussion
When we invoke other DTML methods from python or perl (eg
standard_html_header
above) then we need to pass the client object
for lookups as a separate argument.
The perl method is almost identical to the python method. The only strange thing going on is how we pass in keyword parameters. In this case we have used the glob trick (see Python::Object).