<!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">&nbsp;&nbsp;&nbsp; return mapply( something, blahblah...)</FONT>

<BR><FONT SIZE=2 FACE="Arial">finally:</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; 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.&nbsp; 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.&nbsp; The implementation is pasted below.&nbsp; Is there some much simpler way to accomplish this behavior?&nbsp; 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">&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;voodoo&quot;&quot;&quot;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; id = meta_type = title = &quot;Wrapper&quot;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; def __init__(self, publishable):</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.pub = publishable</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; def index_html(self):</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; render the results to the client</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REQUEST = self.REQUEST</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print self.__class__.__name__, 'calling', self.pub</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mapply(self.pub, REQUEST.args, REQUEST,</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call_object,1,</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; missing_name,</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dont_publish_class,</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; REQUEST, bind=1)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finally:</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print self.__class__.__name__, 'done'</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print ''</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print ''</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; __call__ = index_html</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; </FONT>

<BR><FONT SIZE=2 FACE="Arial">Globals.InitializeClass(Wrapper)&nbsp;&nbsp;&nbsp; </FONT>
</P>
<BR>

<P><FONT SIZE=2 FACE="Arial">class SpecialFolder(Folder):</FONT>
</P>

<P><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp; def __bobo_traverse__ (self,REQUEST,key):</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print '__bobo_traverse__', REQUEST.URL, key</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stack = REQUEST['TraversalRequestNameStack']</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; target = getattr(self,key)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if stack: return target</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Wrapper(target).__of__(self)</FONT>

<BR><FONT SIZE=2 FACE="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </FONT>
</P>

</BODY>
</HTML>