From 95f2b55de1a0f5992eb801da56a1aad3b96547ed Mon Sep 17 00:00:00 2001 From: helmutm Date: Fri, 14 Dec 2007 15:14:15 +0000 Subject: [PATCH] prepare NodeAdapter stuff; refactor version as preparation for i18n-aware resources git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2245 fd906abe-77d9-0310-91a1-e0d9ade77398 --- interfaces.py | 25 +++++++++++++++++-------- tests/setup.py | 3 +++ versioning/versionable.py | 38 ++++++++++++++++++++++---------------- view.py | 17 ++++++++++++++++- 4 files changed, 58 insertions(+), 25 deletions(-) diff --git a/interfaces.py b/interfaces.py index c8de202..217055a 100644 --- a/interfaces.py +++ b/interfaces.py @@ -419,14 +419,7 @@ class IBaseNode(IOrderedContainer): """ -class INode(IView, IBaseNode): - """ A node is a view that may contain other views, thus building a - menu or folder hierarchy. - - A node may be a content object on its own; for this reason it - has a body attribute that may be shown e.g. on web pages. - """ - contains(IView) +class INodeSchema(IView): nodeType = schema.Choice( title=_(u'Node Type'), @@ -449,6 +442,16 @@ class INode(IView, IBaseNode): contentType = Attribute(_(u'Content type (format) of the body')) + +class INode(INodeSchema, IBaseNode): + """ A node is a view that may contain other views, thus building a + menu or folder hierarchy. + + A node may be a content object on its own; for this reason it + has a body attribute that may be shown e.g. on web pages. + """ + contains(IView) + def getParentNode(nodeTypes=None): """ Return the next node up the node hierarchy. If the nodeTypes parameter is given, search for the next node that has one of @@ -488,6 +491,12 @@ class INode(IView, IBaseNode): """ +class INodeAdapter(Interface): + """ Base interface for adapters that provide nodes with additional + capabilities. + """ + + class IViewManager(ILoopsObject, IBaseNode): """ A manager/container for views. """ diff --git a/tests/setup.py b/tests/setup.py index 11fcc36..9d6b9ef 100644 --- a/tests/setup.py +++ b/tests/setup.py @@ -42,6 +42,8 @@ from loops.resource import IndexAttributes as ResourceIndexAttributes from loops.schema import ResourceSchemaFactory, FileSchemaFactory, NoteSchemaFactory from loops.setup import SetupManager, addObject from loops.type import LoopsType, ConceptType, ResourceType, TypeConcept +from loops.view import NodeAdapter + class ClientIdManager(object): """ dummy, for testing only """ @@ -78,6 +80,7 @@ class TestSite(object): component.provideAdapter(TypeConcept) component.provideAdapter(FileAdapter, provides=IFile) component.provideAdapter(TextDocumentAdapter, provides=ITextDocument) + component.provideAdapter(NodeAdapter) component.provideAdapter(NameChooser) component.provideAdapter(Instance) component.provideAdapter(Editor, name='editor') diff --git a/versioning/versionable.py b/versioning/versionable.py index 9881b02..cdd5474 100644 --- a/versioning/versionable.py +++ b/versioning/versionable.py @@ -112,24 +112,17 @@ class VersionableResource(object): m = self.versionableMaster return self.versionableMaster.getVersioningAttribute('releasedVersion', None) - def createVersion(self, level=1, comment=u''): - context = self.context + def createVersionObject(self, versionNumbers, variantIds, comment=u''): versionableMaster = self.versionableMaster - # get the new version numbers - vn = list(IVersionable(self.currentVersion).versionNumbers) - while len(vn) <= level: - vn.append(1) - vn[level] += 1 - for l in range(level+1, len(vn)): - # reset lower levels - vn[l] = 1 - # create new object + versionableMaster.initVersions() + context = self.context + # create object cls = context.__class__ obj = cls() # set versioning attributes of new object versionableObj = IVersionable(obj) - versionableObj.setVersioningAttribute('versionNumbers', tuple(vn)) - versionableObj.setVersioningAttribute('variantIds', self.variantIds) + versionableObj.setVersioningAttribute('versionNumbers', tuple(versionNumbers)) + versionableObj.setVersioningAttribute('variantIds', variantIds) versionableObj.setVersioningAttribute('master', self.master) versionableObj.setVersioningAttribute('parent', context) versionableObj.setVersioningAttribute('comment', comment) @@ -139,6 +132,8 @@ class VersionableResource(object): extensions.get(context.contentType, ''), versionId) getParent(context)[name] = obj + # record version on master + self.versions[versionableObj.versionId] = obj # set resource attributes ti = IType(context).typeInterface attrs = set((ti and list(ti) or []) @@ -147,10 +142,21 @@ class VersionableResource(object): adaptedObj = ti and ti(obj) or obj for attr in attrs: setattr(adaptedObj, attr, getattr(adaptedContext, attr)) + return obj + + def createVersion(self, level=1, comment=u''): + # get the new version numbers + vn = list(IVersionable(self.currentVersion).versionNumbers) + while len(vn) <= level: + vn.append(1) + vn[level] += 1 + for l in range(level+1, len(vn)): + # reset lower levels + vn[l] = 1 + # create new object + obj = self.createVersionObject(vn, self.variantIds, comment) # set attributes of the master version - versionableMaster.setVersioningAttribute('currentVersion', obj) - versionableMaster.initVersions() - self.versions[versionId] = obj + self.versionableMaster.setVersioningAttribute('currentVersion', obj) return obj def generateName(self, name, ext, versionId): diff --git a/view.py b/view.py index 88e2c4a..942fe86 100644 --- a/view.py +++ b/view.py @@ -42,7 +42,8 @@ from cybertools.relation.interfaces import IRelationRegistry, IRelatable from cybertools.util.jeep import Jeep from loops.base import ParentInfo -from loops.interfaces import IView, INode +from loops.common import AdapterBase +from loops.interfaces import IView, INode, INodeSchema, INodeAdapter from loops.interfaces import IViewManager, INodeContained from loops.interfaces import ILoopsContained from loops.interfaces import ITargetRelation @@ -196,6 +197,20 @@ class TargetRelation(DyadicRelation): # adapters +class NodeAdapter(AdapterBase): + """ Allows nodes to be adapted like concepts and resources, e.g. + for i18n (needs derivation from I18NAdapterBase), + specific capabilities or dynamic attributes. + """ + + implements(INodeAdapter) + adapts(INode) + + _contextAttributes = ('title', 'description', 'body',) + + +# traveral adapter + class NodeTraverser(ItemTraverser): adapts(INode)