Author: jmorliaguet Date: Fri Apr 21 00:07:08 2006 New Revision: 2919 Modified: cpsskins/branches/paris-sprint-2006/browser/negotiation/README.txt cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py cpsskins/branches/paris-sprint-2006/browser/tree/slot.py cpsskins/branches/paris-sprint-2006/doc/portlet-ordering.txt cpsskins/branches/paris-sprint-2006/elements/display.py cpsskins/branches/paris-sprint-2006/elements/format.py cpsskins/branches/paris-sprint-2006/relations/tool.py cpsskins/branches/paris-sprint-2006/setup/README.txt cpsskins/branches/paris-sprint-2006/setup/manager.py cpsskins/branches/paris-sprint-2006/setup/registration.py cpsskins/branches/paris-sprint-2006/setup/settings.py cpsskins/branches/paris-sprint-2006/tests/setup.py cpsskins/branches/paris-sprint-2006/thememanager.py cpsskins/branches/paris-sprint-2006/ui/icons/configure.zcml cpsskins/branches/paris-sprint-2006/ui/manager/views.py cpsskins/branches/paris-sprint-2006/ui/panels/settings_section.pt cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/configure.zcml cpsskins/branches/paris-sprint-2006/utils.py Log:
- moved to the new utility registration API Modified: cpsskins/branches/paris-sprint-2006/browser/negotiation/README.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/browser/negotiation/README.txt (original) +++ cpsskins/branches/paris-sprint-2006/browser/negotiation/README.txt Fri Apr 21 00:07:08 2006 @@ -64,8 +64,12 @@ >>> request = TestRequest() >>> root = getRootFolder() + + >>> from cpsskins.tests.setup import makeSite >>> from cpsskins.tests.setup import addThemeSkeleton, addThemeManager - >>> manager = addThemeManager(root) + + >>> manager = addThemeManager(root, makeSite(root)) + >>> theme1 = addThemeSkeleton(manager, u'Theme 1') >>> theme2 = addThemeSkeleton(manager, u'Theme 2') >>> theme3 = addThemeSkeleton(manager, u'Theme 3') @@ -84,8 +88,8 @@ If nothing is specified, the default theme is returned: >>> theme = negotiation.getTheme() - >>> theme.name - u'Theme' + >>> theme + Theme('Theme 1') >>> manager.isDefault(theme) True @@ -95,8 +99,8 @@ >>> request.form[u'theme'] = u'Theme-2' >>> theme = negotiation.getTheme() - >>> theme.name - u'Theme-2' + >>> theme + Theme('Theme 2') >>> del request.form[u'theme'] Modified: cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py (original) +++ cpsskins/branches/paris-sprint-2006/browser/rendering/viewer.py Fri Apr 21 00:07:08 2006 @@ -35,6 +35,7 @@ from cpsskins.elements.interfaces import ( INodeTraverser, INode, IElement, ISlot, IDisplayable) from cpsskins.relations.interfaces import IRelationStorage +from cpsskins.utils import getThemeManager logger = logging.getLogger("cpsskins") @@ -70,7 +71,7 @@ contexts = {} tree = contexts['tree'] = {} - relations = getUtility(IRelationStorage, context=element) + relations = getThemeManager(element).getRelationStorage() negotiation = getMultiAdapter((element, request), INegotiation, 'negotiation') perspective = negotiation.getPerspective() Modified: cpsskins/branches/paris-sprint-2006/browser/tree/slot.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/browser/tree/slot.py (original) +++ cpsskins/branches/paris-sprint-2006/browser/tree/slot.py Fri Apr 21 00:07:08 2006 @@ -33,6 +33,7 @@ from cpsskins.browser.tree.interfaces import ( INodeAdding, INodeRemoving, INodeOrdering, INodeMoving, INodeDuplicating ) +from cpsskins.utils import getThemeManager class SlotAdding(Adding): """A view for adding elements into slots @@ -55,7 +56,7 @@ # a slot is not a container, it is a collection of references to # portlets that are physically stored in a portlet folder. - portlets = getUtility(IPortletStorage, context=container) + portlets = getThemeManager(container).getPortletStorage() portlets.add(content) if perspective is None: @@ -72,7 +73,7 @@ third=perspective, ) - relations = getUtility(IRelationStorage, context=container) + relations = getThemeManager(container).getRelationStorage() relations.add(relation) content.__parent__ = container @@ -129,7 +130,7 @@ third=perspective, ) - relations = getUtility(IRelationStorage, context=dest_container) + relations = getThemeManager(dest_container).getRelationStorage() relations.add(relation) # remove old src_slot -> portlet relations @@ -158,7 +159,7 @@ name='negotiation', ).getPerspective() - portlets = getUtility(IPortletStorage, context=container) + portlets = getThemeManager(container).getPortletStorage() reltool = IRelationTool(container) if perspective is None: @@ -236,7 +237,7 @@ if not IPortlet.providedBy(content): raise TypeError("Only portlets can be duplicated inside slots") - portlets = getUtility(IPortletStorage, context=container) + portlets = getThemeManager(container).getPortletStorage() duplicated = portlets.duplicate(content) Modified: cpsskins/branches/paris-sprint-2006/doc/portlet-ordering.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/doc/portlet-ordering.txt (original) +++ cpsskins/branches/paris-sprint-2006/doc/portlet-ordering.txt Fri Apr 21 00:07:08 2006 @@ -7,9 +7,10 @@ We set up some test environment: + >>> from cpsskins.tests.setup import makeSite >>> from cpsskins.tests.setup import addThemeManager, addThemeSkeleton >>> root = getRootFolder() - >>> tmutil = addThemeManager(root) + >>> tmutil = addThemeManager(root, makeSite(root)) Let us create a theme with two slots ('slot_A', 'slot_B'): Modified: cpsskins/branches/paris-sprint-2006/elements/display.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/display.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/display.py Fri Apr 21 00:07:08 2006 @@ -33,6 +33,7 @@ from cpsskins.relations.interfaces import IRelationTool from cpsskins.ontology import hasDisplay, hasDisplayFromPerspective from cpsskins.standard.displays.storage import IDisplayStorage +from cpsskins.utils import getThemeManager class Display(Element): @@ -120,7 +121,7 @@ return default def storeDisplay(self, display): - displays = getUtility(IDisplayStorage, context=self.context) + displays = getThemeManager(self.context).getDisplayStorage() return displays.add(display) def cloneDisplay(self, display): Modified: cpsskins/branches/paris-sprint-2006/elements/format.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/elements/format.py (original) +++ cpsskins/branches/paris-sprint-2006/elements/format.py Fri Apr 21 00:07:08 2006 @@ -30,6 +30,7 @@ from cpsskins.relations import DyadicRelation from cpsskins.relations.interfaces import IRelationTool from cpsskins.setup.interfaces import IResource, ISetting +from cpsskins.utils import getThemeManager class Format(Element): @@ -102,11 +103,11 @@ return getattr(self, name) def storeFormat(self, format=None): - formats = getUtility(IFormatStorage, context=self.context) + formats = getThemeManager(self.context).getFormatStorage() return formats.add(format) def unstoreFormat(self, format=None): - formats = getUtility(IFormatStorage, context=self.context) + formats = getThemeManager(self.context).getFormatStorage() return formats.remove(format) def getFormats(self, name=u'', resolve=True): Modified: cpsskins/branches/paris-sprint-2006/relations/tool.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/relations/tool.py (original) +++ cpsskins/branches/paris-sprint-2006/relations/tool.py Fri Apr 21 00:07:08 2006 @@ -18,9 +18,9 @@ __docformat__ = "reStructuredText" from zope.interface import implements -from zope.component import getUtility -from cpsskins.relations.interfaces import IRelationTool, IRelationStorage +from cpsskins.relations.interfaces import IRelationTool +from cpsskins.utils import getThemeManager class RelationTool(object): @@ -28,35 +28,33 @@ def __init__(self, context): self.context = context - self.storage = getUtility(IRelationStorage, context=context) - - def getStorage(self): - return self.storage + self.storage = getThemeManager(context).getRelationStorage() def search(self, **kw): - return self.getStorage().search(**kw) + return self.storage.search(**kw) def add(self, relation): - return self.getStorage().add(relation) + return self.storage.add(relation) def get(self, k): - storage = self.getStorage() + storage = self.storage if k in storage: return storage[k] raise KeyError, "No such relation (%s) in the storage." % k def list(self, predicate=None): - return self.getStorage().list(predicate) + return self.storage.list(predicate) def getFirsts(self, **kw): - return self.getStorage().getFirsts(**kw) + return self.storage.getFirsts(**kw) def getSeconds(self, **kw): - return self.getStorage().getSeconds(**kw) + return self.storage.getSeconds(**kw) def getThirds(self, **kw): - return self.getStorage().getThirds(**kw) + return self.storage.getThirds(**kw) def remove(self, ids=[]): if ids: - return self.getStorage().remove(ids) + return self.storage.remove(ids) + Modified: cpsskins/branches/paris-sprint-2006/setup/README.txt ============================================================================== --- cpsskins/branches/paris-sprint-2006/setup/README.txt (original) +++ cpsskins/branches/paris-sprint-2006/setup/README.txt Fri Apr 21 00:07:08 2006 @@ -41,12 +41,19 @@ >>> from cpsskins.setup.test.dummy import IDummyResource, DummyResource >>> from cpsskins.tests.setup import addThemeManager + >>> from cpsskins.thememanager import IThemeManagementFolder >>> root = getRootFolder() - >>> tmutil = addThemeManager(root) + >>> from cpsskins.tests.setup import makeSite + >>> from cpsskins.tests.setup import addThemeSkeleton, addThemeManager - >>> ztapi.provideUtility(IResourceManager, ResourceManager()) + >>> tmutil = addThemeManager(root, makeSite(root)) + + >>> from cpsskins.utils import getThemeManager + >>> getThemeManager(root) is tmutil + True + >>> ztapi.provideUtility(IResourceManager, ResourceManager()) We create a couple of resources: Modified: cpsskins/branches/paris-sprint-2006/setup/manager.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/setup/manager.py (original) +++ cpsskins/branches/paris-sprint-2006/setup/manager.py Fri Apr 21 00:07:08 2006 @@ -19,19 +19,15 @@ from copy import deepcopy -from zope.app import zapi -from zope.app.component.interfaces.registration import ActiveStatus -from zope.app.component.interfaces.registration import InactiveStatus -from zope.app.component.site import UtilityRegistration from zope.app.container.interfaces import INameChooser from zope.interface import implements -from zope.component import (getUtilitiesFor, queryUtility, getUtility, - provideUtility, providedBy) +from zope.component import getGlobalSiteManager +from zope.component import providedBy from cpsskins.setup.interfaces import IResourceManager, IResource from cpsskins.setup.interfaces import ISetting, IGlobalSetting, ILocalSetting from cpsskins.setup.setting import GlobalSetting, LocalSetting -from cpsskins.setup.settings import ISettings +from cpsskins.utils import getThemeManager class ResourceManager(object): """Resource manager utility""" @@ -41,6 +37,8 @@ def __init__(self, context=None): self.context = context + self.gsm = getGlobalSiteManager() + ################################################################### # Registration ################################################################### @@ -53,20 +51,17 @@ if context is None: setting = GlobalSetting(name=name, title=title, resource=resource, filename=filename) - provideUtility(setting, ISetting, name) + self.gsm.registerUtility(setting, ISetting, name) # register as a local utility else: - settings = getUtility(ISettings, context=context) + settings = getThemeManager(context).getSettings() chooser = INameChooser(settings) name = name or chooser.chooseName(title, object) setting = LocalSetting(name=name, title=title, resource=resource, custom=custom) settings[name] = setting - - reg = UtilityRegistration(name, ISetting, settings[name]) - settings.registrationManager.addRegistration(reg) - reg.status = ActiveStatus + settings.registerUtility(setting, ISetting, name) def unregister(self, name=u'', context=None): """Unregister the setting. @@ -77,18 +72,12 @@ if context is None: raise ValueError("Must specify a context.") - setting = queryUtility(ISetting, name, context=context) + settings = getThemeManager(context).getSettings() + setting = settings.queryUtility(ISetting, name) if setting is None or not setting.isLocal(): raise ValueError("No such local setting: '%s'" % name) - settings = getUtility(ISettings, context=context) - regManager = settings.registrationManager - for reg in list(regManager.values()): - if reg.provided.isOrExtends(ISetting) and name == reg.name: - reg.status = InactiveStatus - del regManager[zapi.name(reg)] - del settings[name] - break + settings.unregisterUtility(provided=ISetting, name=name) ################################################################### # Finding resources @@ -98,7 +87,15 @@ if not name: raise KeyError("Must specify a resource name.") - setting = queryUtility(ISetting, name, context=context) + setting = None + + if context is not None: + settings = getThemeManager(context).getSettings() + setting = settings.queryUtility(ISetting, name) + + if context is None or setting is None: + setting = self.gsm.queryUtility(ISetting, name) + if setting is None: return default @@ -108,35 +105,45 @@ return default def list(self, type=None, context=None): - resources = [] - for name, setting in getUtilitiesFor(ISetting, context=context): + + items = {} + + entries = list(self.gsm.getUtilitiesFor(ISetting)) + if context is not None: + settings = getThemeManager(context).getSettings() + entries.extend(list(settings.getUtilitiesFor(ISetting))) + + for name, setting in entries: resource_getter = IResource(setting, None) if resource_getter is None: continue resource = resource_getter.getResource() if type and not type in list(providedBy(resource)): continue - resources.append(resource) - return resources + items[name] = resource + return items.values() ################################################################### # Customization ################################################################### def isGlobal(self, name=u''): - setting = queryUtility(ISetting, name) + setting = self.gsm.queryUtility(ISetting, name) if setting is None: raise ValueError("No such setting: '%s'." % name) return IGlobalSetting.providedBy(setting) def isLocal(self, name=u'', context=None): - setting = queryUtility(ISetting, name, context=context) + settings = getThemeManager(context).getSettings() + setting = settings.queryUtility(ISetting, name) + if setting is None: raise ValueError("No such setting: '%s'." % name) return ILocalSetting.providedBy(setting) def isCustom(self, name=u'', context=None): - setting = queryUtility(ISetting, name, context=context) + settings = getThemeManager(context).getSettings() + setting = settings.queryUtility(ISetting, name) if setting is None: raise ValueError("No such setting: '%s'." % name) return ILocalSetting.providedBy(setting) and setting.custom @@ -145,7 +152,7 @@ if context is None: raise ValueError("Must specify a context.") - setting = queryUtility(ISetting, name) + setting = self.gsm.queryUtility(ISetting, name) if setting is None: raise ValueError("No such setting: '%s'." % name) @@ -164,7 +171,7 @@ if context is None: raise ValueError("Must specify a context.") - if queryUtility(ISetting, name) is None: + if self.gsm.queryUtility(ISetting, name) is None: raise ValueError("No such customized setting.") self.unregister(name=name, context=context) Modified: cpsskins/branches/paris-sprint-2006/setup/registration.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/setup/registration.py (original) +++ cpsskins/branches/paris-sprint-2006/setup/registration.py Fri Apr 21 00:07:08 2006 @@ -26,6 +26,7 @@ from xml.parsers.expat import ExpatError from zope.component import getUtility, queryUtility, createObject +from zope.component import getGlobalSiteManager from cpsskins.setup.interfaces import IResourceManager, IDataImporter from cpsskins.setup.interfaces import ISetting, IResource @@ -118,7 +119,7 @@ def reloadSetting(name=u''): """Reload a setting by name. """ - setting = getUtility(ISetting, name) + setting = getGlobalSiteManager().queryUtility(ISetting, name) filename = setting.filename if not filename: Modified: cpsskins/branches/paris-sprint-2006/setup/settings.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/setup/settings.py (original) +++ cpsskins/branches/paris-sprint-2006/setup/settings.py Fri Apr 21 00:07:08 2006 @@ -17,13 +17,19 @@ """ __docformat__ = "reStructuredText" -from zope.app.component.site import SiteManagementFolder +from zope.app.container.btree import BTreeContainer +from zope.component.persistentregistry import PersistentComponents + from zope.interface import implements, Interface class ISettings(Interface): """ """ -class Settings(SiteManagementFolder): +class Settings(BTreeContainer, PersistentComponents): implements(ISettings) + def __init__(self): + super(Settings, self).__init__() + PersistentComponents.__init__(self) + Modified: cpsskins/branches/paris-sprint-2006/tests/setup.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/tests/setup.py (original) +++ cpsskins/branches/paris-sprint-2006/tests/setup.py Fri Apr 21 00:07:08 2006 @@ -62,9 +62,12 @@ ztapi.subscribe([IElement, IObjectModifiedEvent], None, controllers.elementModified) -def addThemeManager(root): +def makeSite(root): + return setup.createSiteManager(root, True) + +def addThemeManager(root, sm): tmutil = root[u'themes'] = ThemeManagementFolder() - ztapi.provideUtility(IThemeManagementFolder, tmutil, name=u'themes') + sm.registerUtility(tmutil, IThemeManagementFolder) return tmutil def addThemeSkeleton(context, title=u'A theme'): Modified: cpsskins/branches/paris-sprint-2006/thememanager.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/thememanager.py (original) +++ cpsskins/branches/paris-sprint-2006/thememanager.py Fri Apr 21 00:07:08 2006 @@ -20,16 +20,16 @@ import logging from zope.app import zapi -from zope.app.component.interfaces.registration import ActiveStatus -from zope.app.component.site import SiteManagementFolder, UtilityRegistration from zope.app.container.interfaces import INameChooser +from zope.component.persistentregistry import PersistentComponents +from zope.component import getUtility from zope.app.intid import IntIds from zope.app.intid.interfaces import IIntIds from zope.traversing.api import getParent -from zope.component import getUtilitiesFor, getUtility from zope.interface import implements, Interface from zope.i18nmessageid import MessageFactory from zope.schema import TextLine +from zope.app.container.btree import BTreeContainer from cpsskins.caching import ImageCache, IImageCache from cpsskins.elements.interfaces import IFormattable @@ -75,6 +75,21 @@ def getRelationStorage(): """Return the relation storage.""" + def getDisplayStorage(): + """Return the display storage.""" + + def getFormatStorage(): + """Return the format storage.""" + + def getSnapshotStorage(): + """Return the snapshot storage.""" + + def getPortletStorage(): + """Return the portlet storage.""" + + def getSettings(): + """Return the settings.""" + def registerElement(element): """Add an element to the unique id registry.""" @@ -118,7 +133,7 @@ def listPerspectives(): """ """ -class ThemeManagementFolder(SiteManagementFolder): +class ThemeManagementFolder(BTreeContainer, PersistentComponents): """A theme management utility that can contain multiple . themes @@ -136,7 +151,8 @@ implements(IThemeManagementFolder, IThemeContainer) def __init__(self, negotiation=u'default'): - super(ThemeManagementFolder, self).__init__() + BTreeContainer.__init__(self) + PersistentComponents.__init__(self) # negotiation strategy self.negotiation = negotiation # registries, storages, etc. @@ -155,31 +171,38 @@ ################################################################### def registerUtilities(self): - self.registerUtility(IIntIds, self[u'uids']) - self.registerUtility(ISnapshotStorage, self[u'snapshots']) - self.registerUtility(IImageCache, self[u'imagecache']) - self.registerUtility(ISettings, self[u'settings']) - self.registerUtility(IRelationStorage, self[u'relations']) - self.registerUtility(IPortletStorage, self[u'portlets']) - self.registerUtility(IDisplayStorage, self[u'displays']) - self.registerUtility(IFormatStorage, self[u'formats']) - - def registerUtility(self, interface, utility): - reg = UtilityRegistration('', interface, utility) - self.registrationManager.addRegistration(reg) - reg.status = ActiveStatus + self.registerUtility(self[u'uids'], IIntIds) + self.registerUtility(self[u'snapshots'], ISnapshotStorage) + self.registerUtility(self[u'imagecache'], IImageCache) + self.registerUtility(self[u'settings'], ISettings) + self.registerUtility(self[u'relations'], IRelationStorage) + self.registerUtility(self[u'portlets'], IPortletStorage) + self.registerUtility(self[u'displays'], IDisplayStorage) + self.registerUtility(self[u'formats'], IFormatStorage) def getIdRegistry(self): - return getUtility(IIntIds, context=self) + return self.getUtility(IIntIds) def getImageCache(self): - return getUtility(IImageCache, context=self) + return self.getUtility(IImageCache) def getRelationStorage(self): - return getUtility(IRelationStorage, context=self) + return self.getUtility(IRelationStorage) + + def getDisplayStorage(self): + return self.getUtility(IDisplayStorage) + + def getFormatStorage(self): + return self.getUtility(IFormatStorage) + + def getPortletStorage(self): + return self.getUtility(IPortletStorage) def getSnapshotStorage(self): - return getUtility(ISnapshotStorage, context=self) + return self.getUtility(ISnapshotStorage) + + def getSettings(self): + return self.getUtility(ISettings) ################################################################### # Unique id registry @@ -220,20 +243,18 @@ name = INameChooser(self).chooseName(u'', theme) self[name] = theme # register the theme as a local utility - theme_reg = UtilityRegistration(name, ITheme, theme) - self.registrationManager.addRegistration(theme_reg) - theme_reg.status = ActiveStatus + self.registerUtility(theme, ITheme, name) return name def getThemes(self): """Return the list of themes """ - return [theme for name, theme in getUtilitiesFor(ITheme, self)] + return [theme for name, theme in self.getUtilitiesFor(ITheme)] def getThemeByName(self, name=u''): """Return a theme by its name. """ - for k, v in getUtilitiesFor(ITheme, self): + for k, v in self.getUtilitiesFor(ITheme): if k == name: return v return None @@ -241,7 +262,7 @@ def getPageByName(self, name=u''): """Return a page by its name. """ - for k, v in getUtilitiesFor(IThemePage, self): + for k, v in self.getUtilitiesFor(IThemePage): if k == name: return v return None @@ -249,14 +270,14 @@ def isDefault(self, object=None): """Return True if the element is used by default """ - relations = getUtility(IRelationStorage, context=object) + relations = self.getRelationStorage() res = relations.search(predicate=isDefault, first=object) return res is not [] def setAsDefault(self, object=None): """Set the default theme """ - relations = getUtility(IRelationStorage, context=object) + relations = self.getRelationStorage() relations.add(MonadicRelation(isDefault, object)) def getDefaultTheme(self): Modified: cpsskins/branches/paris-sprint-2006/ui/icons/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/icons/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/ui/icons/configure.zcml Fri Apr 21 00:07:08 2006 @@ -2,6 +2,7 @@ xmlns="http://namespaces.zope.org/browser" xmlns:zope="http://namespaces.zope.org/zope"> + <!-- <icon name="zmi_icon" for="cpsskins.elements.interfaces.ITheme" file="theme.png" @@ -26,5 +27,6 @@ for="cpsskins.elements.interfaces.ISlot" file="slot.png" /> + --> </configure> Modified: cpsskins/branches/paris-sprint-2006/ui/manager/views.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/manager/views.py (original) +++ cpsskins/branches/paris-sprint-2006/ui/manager/views.py Fri Apr 21 00:07:08 2006 @@ -49,7 +49,7 @@ implements(IThemeManagerView) def getThemeManager(self): - return getThemeManager(self.context) + return self.context def getThemes(self): return self.context.getThemes() Modified: cpsskins/branches/paris-sprint-2006/ui/panels/settings_section.pt ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/panels/settings_section.pt (original) +++ cpsskins/branches/paris-sprint-2006/ui/panels/settings_section.pt Fri Apr 21 00:07:08 2006 @@ -7,7 +7,7 @@ readonly info/readonly; custom info/custom"> <a tal:attributes="href string:@@customizeSetting?name=$name" - tal:condition="readonly">[customize]</a> + tal:condition="not:custom">[customize]</a> <a tal:attributes="href string:@@removeSetting?name=$name" tal:condition="python: not custom and not readonly">[remove]</a> <a tal:attributes="href string:@@decustomizeSetting?name=$name" Modified: cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/ui/screens/sitemanager/configure.zcml Fri Apr 21 00:07:08 2006 @@ -73,6 +73,11 @@ /> <page + name="getSnapshotStorage" + attribute="getSnapshotStorage" + /> + + <page name="listSnapshots" attribute="listSnapshots" /> Modified: cpsskins/branches/paris-sprint-2006/utils.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/utils.py (original) +++ cpsskins/branches/paris-sprint-2006/utils.py Fri Apr 21 00:07:08 2006 @@ -18,10 +18,22 @@ __docformat__ = "reStructuredText" from zope.component import queryUtility, getUtility, getSiteManager +from zope.app.zapi import getParent from cpsskins.setup.interfaces import IResourceManager from cpsskins.thememanager import IThemeManagementFolder def getThemeManager(context): - return getSiteManager(context).queryUtility(IThemeManagementFolder) + mgr = getSiteManager(context).queryUtility(IThemeManagementFolder) + if mgr is not None: + return mgr + + ob = context + while ob is not None: + if IThemeManagementFolder.providedBy(ob): + return ob + ob = getParent(ob) + + return None + -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins