<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.0.6603.0">
<TITLE>the joy of hacking ZPublisher</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/rtf format -->
<P><FONT SIZE=2 FACE="Arial">In my Zope 2.7 Product, I'm trying to implement a special folder, which intercepts the publishing call to any subobject and wraps the entire call in another.</FONT></P>
<P><FONT SIZE=2 FACE="Arial">A concrete example: where the default action would be to traverse /MyProduct/SpecialFolder/something, and publish the attr 'something' from SpecialFolder, I want this to happen instead:</FONT></P>
<P><FONT SIZE=2 FACE="Arial">doSomethingBeforeCallingTheRequestedObj()</FONT>
<BR><FONT SIZE=2 FACE="Arial">try:</FONT>
<BR><FONT SIZE=2 FACE="Arial"> return mapply( something, blahblah...)</FONT>
<BR><FONT SIZE=2 FACE="Arial">finally:</FONT>
<BR><FONT SIZE=2 FACE="Arial"> doSomethingAfterCallingTheRequestedObj()</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial">Why? I need to do stuff to the REQUEST before the object is called (this part wasn't difficult), and then do something *after* it's called - no matter what the results were. But only for publishables that live in or beneath the Special Folder.</FONT></P>
<P><FONT SIZE=2 FACE="Arial">In fact I have something working, but one big problem - it breaks management screens in a bad way. The implementation is pasted below. Is there some much simpler way to accomplish this behavior? And am I short-circuiting security machinery in some dangerous way?</FONT></P>
<BR>
<P><FONT SIZE=2 FACE="Arial">class Wrapper(Implicit):</FONT>
<BR><FONT SIZE=2 FACE="Arial"> """voodoo"""</FONT>
<BR><FONT SIZE=2 FACE="Arial"> </FONT>
<BR><FONT SIZE=2 FACE="Arial"> id = meta_type = title = "Wrapper"</FONT>
<BR><FONT SIZE=2 FACE="Arial"> </FONT>
<BR><FONT SIZE=2 FACE="Arial"> def __init__(self, publishable):</FONT>
<BR><FONT SIZE=2 FACE="Arial"> self.pub = publishable</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial"> def index_html(self):</FONT>
<BR><FONT SIZE=2 FACE="Arial"> """</FONT>
<BR><FONT SIZE=2 FACE="Arial"> render the results to the client</FONT>
<BR><FONT SIZE=2 FACE="Arial"> """</FONT>
<BR><FONT SIZE=2 FACE="Arial"> REQUEST = self.REQUEST</FONT>
<BR><FONT SIZE=2 FACE="Arial"> print self.__class__.__name__, 'calling', self.pub</FONT>
<BR><FONT SIZE=2 FACE="Arial"> try:</FONT>
<BR><FONT SIZE=2 FACE="Arial"> return mapply(self.pub, REQUEST.args, REQUEST,</FONT>
<BR><FONT SIZE=2 FACE="Arial"> call_object,1,</FONT>
<BR><FONT SIZE=2 FACE="Arial"> missing_name,</FONT>
<BR><FONT SIZE=2 FACE="Arial"> dont_publish_class,</FONT>
<BR><FONT SIZE=2 FACE="Arial"> REQUEST, bind=1)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> finally:</FONT>
<BR><FONT SIZE=2 FACE="Arial"> print self.__class__.__name__, 'done'</FONT>
<BR><FONT SIZE=2 FACE="Arial"> print ''</FONT>
<BR><FONT SIZE=2 FACE="Arial"> print ''</FONT>
<BR><FONT SIZE=2 FACE="Arial"> </FONT>
<BR><FONT SIZE=2 FACE="Arial"> __call__ = index_html</FONT>
<BR><FONT SIZE=2 FACE="Arial"> </FONT>
<BR><FONT SIZE=2 FACE="Arial">Globals.InitializeClass(Wrapper) </FONT>
</P>
<BR>
<P><FONT SIZE=2 FACE="Arial">class SpecialFolder(Folder):</FONT>
</P>
<P><FONT SIZE=2 FACE="Arial"> def __bobo_traverse__ (self,REQUEST,key):</FONT>
<BR><FONT SIZE=2 FACE="Arial"> print '__bobo_traverse__', REQUEST.URL, key</FONT>
<BR><FONT SIZE=2 FACE="Arial"> stack = REQUEST['TraversalRequestNameStack']</FONT>
<BR><FONT SIZE=2 FACE="Arial"> target = getattr(self,key)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> if stack: return target</FONT>
<BR><FONT SIZE=2 FACE="Arial"> return Wrapper(target).__of__(self)</FONT>
<BR><FONT SIZE=2 FACE="Arial"> </FONT>
</P>
</BODY>
</HTML>