I already this question some time ago but still haven't found a reasonable solution.
I need to switch the diazo theme from within my policy package based on some condition (specific URL, specific user or role etc) on the fly. Normal requests from anonymous site visitors should use the official site Diazo theme. Internal uses should use Barceloneta. I am not looking for solution the theme level. applyTheme() seems to change the theme for the whole site (theme control panel). I found some code in collective.lineagethemeselection but that seems to refer to the old skin system of CMF or is this approach still valid or what is the official way for dynamically switching the theme (from within a policy package)?
def set_theme_specific_layers(request, context, new_skin, current_skin):
"""mark the request with the browserlayer named new_skin
and remove the one marked with current_skin
we can't be sure plone.theme.layer.mark_layer is called after our traverser
so we add the layer manually.
"""
# check to see the skin has a IBrowserSkinType layer
skin_iface = queryUtility(IBrowserSkinType, new_skin)
if skin_iface:
# remove theme specific layer of the current skin
current_skin_iface = queryUtility(IBrowserSkinType, name=current_skin)
if current_skin_iface is not None:
noLongerProvides(request, current_skin_iface)
# add the layer interface
if skin_iface is not None and not skin_iface.providedBy(request):
alsoProvides(request, skin_iface)
def apply_skin(obj, event):
"""Switch to the skin or theme selected for the child site.
"""
if event.request.get('editskinswitched', False):
# don't switch/set skin if collective.editskinswitcher has set
# the edit skin already
return
alsoProvides(event.request, ILineageThemingLayer)
wrapped_site = LineageSubsiteFacade(obj)
skin = wrapped_site.default_skin
if not skin:
return
current_skin = obj.getCurrentSkinName()
obj.changeSkin(skin, event.request)
set_theme_specific_layers(event.request, obj, skin, current_skin)