[SOLVED] Rendering viewlet without viewlet manager, with browserlayer awareness

I have a simple form where I do not want to render most of the main template with its viewlet managers, but I do want to show just the plone.logo viewlet here. The guide here https://docs.plone.org/develop/plone/views/viewlets.html#rendering-viewlet-by-name gets me most of the way there, except that it doesn't seem to consider browser layer. Indeed in getViewletByName I can debug and see that there are two viewlets with the plone.logo name - one is the default, and the other is my custom one (with some changes to how the logo viewlet works). When rendering most pages, my custom logo viewlet is indeed shown, so I know that the browser layer is properly installed.

One thing I had tried to do was to just call the custom viewlet's class directly, update it, and render it. That works, but isn't browserlayer-aware either. I want my custom page w/viewlet to get the top layer for plone.logo, which will be defined elsewhere.

Try to add

from zope.interface import alsoProvides

(...)

alsoProvides(self.request, IMyBrowserLayer)

Before getting your viewlet.

That won't work because the page calling the viewlet isn't going to know the top browser layer.

I ended up taking a different approach. I specified a viewletmanager, updated, and extracted the appropriate viewlet from it. I believe this lets the viewletmanager handle the browser layering.

def get_viewlet_by_name(self, manager, name):
    manager = queryMultiAdapter((self.context, self.request, BrowserView(self.context, self.request)),
                                IViewletManager, manager, default=None)
    manager.update()

    for viewlet in manager.viewlets:
        if viewlet.__name__ == name:
            return viewlet

def render_viewlet(self, manager, name):
    viewlet = self.get_viewlet_by_name(manager, name)
    if viewlet:
        viewlet.update()
        return viewlet.render()

def logo(self):
    return self.render_viewlet('plone.portalheader', 'plone.logo')
2 Likes

Adding [SOLVED] to your post title would be nice.

@Esoth the icying in the cake would be adding the snippet to https://docs.plone.org/develop/plone/views/viewlets.html (the repository is at https://github.com/plone/documentation) as well.

(With all due respect, this would be a great addition to be somewhere in the core itself, zope.viewlet or somewhere else, but a discussion is needed)