[Zope-dev] Calling in Context

Brian R Brinegar brinegar@ecn.purdue.edu
Fri, 13 Dec 2002 15:43:09 -0500 (EST)


Howdy,

Overview:

I'm working on a helper product for Zope Presentation Templates. The goal
of this product is to allow people to drop static content into a site
developed with Zope Presentation Templates using WebDAV clients. (This is
similar to the Kube Product but it's not folderish and supports WebDAV.)

At first I suggested creating some ZPT with an Id like "view". Have users
drop in static content as File objects. Then link to the files like
"file_id/view". The "view" ZPT would reference the document_src method
of the file object to pull the static content into the page. I like
this approach, and I think this is how Presentation Templates are meant to
be used.

Problem:

Our users will not change links created by WYSIWYG tools to include the
"/view" so we need a product that removes the need for this. I am calling the
product HTMLBlock. Version one of the product is a simple data holder
with a document_src method which returns the content. It does not override
index_html, instead acquiring the index_html from the context. I create an
index_html page template with all of my presentation and some code like:

<div tal:replace="here/document_src">Content Goes Here</div>

When an HTMLBlock is viewed it shows up with all of the dynamic
presentation of the index_html ZPT with the HTMLBlocks static content
dropped in. Great! Almost there! :-)

The problem is that people cannot create a default HTMLBlock with the Id
index_html. It ends up trying to render itself much like a folder with the
Id index_html. No Good. :-(

So I temporarily fixed this by changing the template to redirect to an
object with the Id "index" if document_src doesn't exist. When someone
views a folder the index_html template is accessed, document_src is not
defined so it redirects to "index" which is an HTMLBlock which renders
correctly. I don't like this. :*( Still No Good.

What I want is for the HTMLBlock product to have a property which
specifies the Id of the template to use. Implement an index_html or
__call__ method to locate the template and call it in the context of
itself. I would like this to work generically so that the template could
be DTML, Python, a ZPT, or anything else.

Casey Duncan has some uber useful code on ZopeLabs.com to call an object
generically using the ZPublisher. I borrowed it and came up with the
code below, but it doesn't work. It calls the template, but the template
cannot access methods of this object.

Suggestions? Is there a better approach?

(Note: template_id is the Id of the template to render)

def __call__(self, client=None, REQUEST={}, RESONSE=None, **kw):
   """
   Call the selected template in the context of myself.
   """A

   securityManager = getSecurityManager()
   securityManager.addContext(self)

   # Check for the template
   if not hasattr(self.aq_parent, self.template_id):
      return str(self)

   obj = getattr(self.aq_parent, self.template_id)
   if not securityManager.checkPermission('View', obj):
      return default

   return mapply(
      object=obj,
      positional=REQUEST.args,
      keyword=REQUEST,
      debug=call_object,
      maybe=1,
      missing_name=missing_name,
      handle_class=dont_publish_class,
      context=self,
      bind=1)


The code below works, but requires a PageTemplate with the Id "index" to
work

def __call__(self, client=None, REQUEST={}, RESONSE=None, **kw):
   return self.index()

Thanks,
-Brian