Getting the registered Zope 3 skin name for an interface

Problem: I need to get the skin name for a Zope 3 interface registered as skin.

Solution

Starting with Zope 3.3, the skinning mechanism has been simplified and skins are now just interfaces. This means that a skin interface is now a named utility for the IBrowserSkinType. To get the name with which this class has been registered as an utility, something along these lines is needed:

>>> from myapp.layer import IMyAppSkin
>>> from zope.app.apidoc.component import getUtilities
>>> from zope.publisher.interfaces.browser import IBrowserSkinType
>>> skins = getUtilities(IBrowserSkinType)
>>> for skinreg in skins:
... if skinreg.component == IMyAppSkin:
... skin_name = skinreg.name
... break

I'm using the apidoc module here, which feels a bit like cheating. Another, "apidoc-free" version is something like this:

>>> from zope.component import getGlobalSiteManager
>>> gsm = getGlobalSiteManager()
>>> skins = gsm.getUtilitiesFor(IBrowserSkinType)
>>> for skinreg in skins:
... if IMyAppSkin == skinreg[1]:
... skin_name = skinreg[0]
... break

getUtilitiesFor() returns a list of tuples, for example: [(u'Basic', <InterfaceClass zope.app.basicskin.IBasicSkin>), (u'Debug', <InterfaceClass zope.app.debugskin.IDebugSkin>), ... ]

UPDATE: fixed a small bug in the second example, that's what you get if I don't test...

You can get the current skin interface with:

curentSkinInterface = [iskin for iskin in interface.directlyProvidedBy(self.request) if 
IBrowserSkinType.providedBy(iskin)][0]

Comments