[Zope] Context in a view doesn't see marker interface

Eric Steele ems174 at psu.edu
Tue Jun 24 15:23:11 EDT 2008


On Jun 20, 2008, at 6:27 AM, Chris Withers wrote:

> Eric Steele wrote:
>> If I include something along the lines of <tal:block  
>> tal:replace="structure context" /> in my view template, someObject  
>> renders in the browser. The problem is that none of what's in there  
>> appears to recognize the interface that my view provides.
>
> It's not at all clear what you mean here or what the problem is that  
> you're trying to describe.
>
> How about a concrete, minimal example?
>
> > (I also had some success creating a page template on the fly,  
> injecting
> > the current content object's template code into it along with  
> whatever
> > else I wanted to display, but that just feels icky and runs afoul  
> of the
>
> "feels icky" is an understatement. How about woefully inefficient,  
> not to mention insane? You could probably make it a bit worse by  
> getting the template code from the request if you really tried  
> hard ;-)

Oh, come now. That's just silly...

But really, the only reason I mentioned it was in hopes of goading  
someone into taking action against it. :-P

Ok, a better example... I'm going to start with Plone since that's  
what this is eventually geared towards.

My hoped-for goal is this...If I view the front page of the site  
normally (http://localhost:8080/site/front-page), I'll see it rendered  
with normally. If I view it through my browser view (http://localhost:8080/site/front-page/@@viewletmanagertest 
), it'll render the same bit of content (front-page), but using the  
render method of the viewletmanagers I've adapted to the  
IViewletManagerTestView that my view provides.

So in a stripped down example...

I'd define my interface, view and new viewletmanager:

class IViewletManagerTestView(Interface):
     pass

class ViewletManagerTestView(BrowserView):
     implements(IViewletManagerTestView)
     template = ViewPageTemplateFile('viewletmanagertest.pt')

     def __init__(self, context, request):
         self.context = context
         self.request = request

     def __call__(self):
         return self.template(self.context, self.request)

class OverridingViewletManager(ViewletManagerBase):
     implements(IViewletManager)
     def render(self):
         return "It worked!"

Register my adapters locally:

<adapter name="plone.portalfooter"
       
factory="myapp.browser.viewletmanagertest.OverridingViewletManager"
      for_="zope.interface.Interface
                zope.publisher.interfaces.browser.IBrowserRequest
                 
myapp.browser.viewletmanagertest.IViewletManagerTestView"
      provides="plone.app.layout.viewlets.interfaces.IPortalFooter"/>

and create a template that shows
1) a call to a viewletmanager to make sure the adaptation is working  
at all
2) the content object that the view is called on

<h3>Footer:</h3>
<div tal:replace="structure provider:plone.portalfooter" />

<h3>Content object in context:</h3>
<tal:block tal:replace="structure context" />

So now when I call that view (http://localhost:8080/site/front-page/@@viewletmanagertest 
), I should see Footer: It worked! and then the content object  
rendered with "It worked" in place of the portalfooter viewletmanager.  
Instead, I just see the Footer: It worked! and then the content object  
rendered normally.

The adaptation is working for the view, otherwise that first "it  
worked!" wouldn't show up. The problem lies in calling the content  
object through that <tal:block tal:replace="structure context" /> bit.  
If I place the page template's code directly into my view template,  
everything works perfectly.

I hope that's at least somewhat of a better explanation of what I'm  
after.

Eric


More information about the Zope mailing list