You are not logged in Log in Join
You are here: Home » Members » andym » wiki » ScriptperlPod

Log in
Name

Password

 
 
FrontPage »

ScriptperlPod

  • NAME
  • DESCRIPTION
  • EXAMPLE 1
  • EXAMPLE 2

  • 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).