Back to index

plone3  3.1.7
registration.py
Go to the documentation of this file.
00001 from Products.Five.browser import BrowserView
00002 from five.customerize.interfaces import IViewTemplateContainer, ITTWViewTemplate
00003 from five.customerize.browser import mangleAbsoluteFilename
00004 from five.customerize.zpt import TTWViewTemplate
00005 from five.customerize.utils import findViewletTemplate
00006 from zope.publisher.interfaces.browser import IBrowserRequest
00007 from zope.component import getGlobalSiteManager, getUtility
00008 from zope.component import getAllUtilitiesRegisteredFor
00009 from zope.viewlet.interfaces import IViewlet
00010 from plone.portlets.interfaces import IPortletRenderer
00011 from plone.browserlayer.interfaces import ILocalBrowserLayerType
00012 from os.path import basename
00013 
00014 
00015 def getViews(type):
00016     """ get all view registrations (stolen from zope.app.apidoc.presentation),
00017         both global and those registered for a specific layer """
00018         
00019     # A zope 3 view is any multi-adapter whose second requirement is a browser request,
00020     # or derivation thereof.  We also do an explicit check for interfaces that have
00021     # been registered as plone.browserlayer browser layers, because often these
00022     # do not extend IBrowserRequest even though they should.
00023     layers = getAllUtilitiesRegisteredFor(ILocalBrowserLayerType)
00024     gsm = getGlobalSiteManager()
00025     for reg in gsm.registeredAdapters():
00026         if (len(reg.required) > 1 and
00027                 reg.required[1] is not None and
00028                (reg.required[1].isOrExtends(type) or
00029                 reg.required[1] in layers)):
00030             yield reg
00031 
00032 def interfaceName(iface):
00033     """ return a sensible name for the given interface """
00034     name = getattr(iface, '__name__', repr(iface))
00035     return getattr(iface, '__identifier__', name)
00036 
00037 def templateViewRegistrations():
00038     regs = []
00039     for reg in getViews(IBrowserRequest):
00040         factory = reg.factory
00041         while hasattr(factory, 'factory'):
00042             factory = factory.factory
00043         # TODO: this should really be dealt with using
00044         # a marker interface on the view factory
00045         name = getattr(factory, '__name__', '')
00046         if name.startswith('SimpleViewClass') or \
00047                 name.startswith('SimpleViewletClass') or \
00048                 name.endswith('Viewlet') or \
00049                 IViewlet.implementedBy(factory) or \
00050                 IPortletRenderer.implementedBy(factory):
00051             attr, pt = findViewletTemplate(factory)
00052             if pt:
00053                 reg.ptname = basename(pt.filename)
00054             else:
00055                 reg.ptname = None
00056             regs.append(reg)
00057     return regs
00058 
00059 def templateViewRegistrationInfos(regs):
00060     for reg in regs:
00061         if ITTWViewTemplate.providedBy(reg.factory):
00062             zptfile = None
00063             zcmlfile = None
00064             name = reg.name or reg.factory.name
00065             customized = reg.factory.getId()    # TODO: can we get an absolute url?
00066         else:
00067             attr, pt = findViewletTemplate(reg.factory)
00068             if attr is None:        # skip, if the factory has no template...
00069                 continue
00070             zptfile = mangleAbsoluteFilename(pt.filename)
00071             zcmlfile = getattr(reg.info, 'file', None)
00072             zcmlfile = zcmlfile and mangleAbsoluteFilename(zcmlfile)
00073             name = reg.name or basename(zptfile)
00074             customized = None
00075         required = [interfaceName(r) for r in reg.required]
00076         yield {
00077             'viewname': name,
00078             'required': ','.join(required),
00079             'for': required[0],
00080             'type': required[1],
00081             'zptfile': zptfile,
00082             'zcmlfile': zcmlfile or 'n.a.',
00083             'customized': customized,
00084         }
00085 
00086 def templateViewRegistrationGroups(regs):
00087     ifaces = {}
00088     comp = lambda a,b: cmp(a['viewname'], b['viewname'])
00089     for reg in sorted(templateViewRegistrationInfos(regs), cmp=comp):
00090         key = reg['for']
00091         if ifaces.has_key(key):
00092             ifaces[key]['views'].append(reg)
00093         else:
00094             ifaces[key] = { 'name': key, 'views': [reg] }
00095     return sorted(ifaces.values(), cmp=lambda a,b: cmp(a['name'], b['name']))
00096 
00097 def findTemplateViewRegistration(required, viewname):
00098     required = required.split(',')
00099     for reg in templateViewRegistrations():
00100         if required == [interfaceName(r) for r in reg.required]:
00101             if reg.name == viewname or reg.provided.isOrExtends(IPortletRenderer):
00102                 return reg
00103 
00104 def generateIdFromRegistration(reg):
00105     return '%s-%s' % (
00106         interfaceName(reg.required[0]).lower(),
00107         reg.name or reg.ptname
00108     )
00109 
00110 def getViewClassFromRegistration(reg):
00111     # The view class is generally auto-generated, we usually want
00112     # the first base class, though if the view only has one base
00113     # (generally object or BrowserView) we return the full class
00114     # and hope that it can be pickled
00115     if IPortletRenderer.implementedBy(reg.factory):
00116         return reg.factory
00117     klass = reg.factory
00118     base = klass.__bases__[0]
00119     if base is BrowserView or base is object:
00120         return klass
00121     return base
00122 
00123 def getTemplateCodeFromRegistration(reg):
00124     attr, template = findViewletTemplate(reg.factory)
00125     # TODO: we can't do template.read() here because of a bug in
00126     # Zope 3's ZPT implementation.
00127     return open(template.filename, 'rb').read()
00128 
00129 def getViewPermissionFromRegistration(reg):
00130     permissions = getattr(reg.factory, '__ac_permissions__', [])
00131     for permission, methods in permissions:
00132         if methods[0] in ('', '__call__'):
00133             return permission
00134 
00135 def createTTWViewTemplate(reg):
00136     attr, pt = findViewletTemplate(reg.factory)
00137     if pt:
00138         ptname = basename(pt.filename)
00139     else:
00140         ptname = None
00141     return TTWViewTemplate(
00142         id = str(generateIdFromRegistration(reg)),
00143         text = getTemplateCodeFromRegistration(reg),
00144         view = getViewClassFromRegistration(reg),
00145         permission = getViewPermissionFromRegistration(reg),
00146         name = ptname)
00147 
00148 def customizeTemplate(reg):
00149     viewzpt = createTTWViewTemplate(reg)
00150     container = getUtility(IViewTemplateContainer)
00151     return container.addTemplate(viewzpt.getId(), viewzpt)
00152