[Zope] 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