Work in progress: working with target objects
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@1041 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
		
							parent
							
								
									3cbba1d593
								
							
						
					
					
						commit
						b02329358a
					
				
					 10 changed files with 144 additions and 36 deletions
				
			
		
							
								
								
									
										31
									
								
								README.txt
									
										
									
									
									
								
							
							
						
						
									
										31
									
								
								README.txt
									
										
									
									
									
								
							|  | @ -30,6 +30,8 @@ top-level loops container and a concept manager: | ||||||
|   >>> concepts['cc1'] = cc1 |   >>> concepts['cc1'] = cc1 | ||||||
|   >>> cc1.title |   >>> cc1.title | ||||||
|   u'' |   u'' | ||||||
|  |   >>> loopsRoot.getLoopsUri(cc1) | ||||||
|  |   '.loops/concepts/cc1' | ||||||
| 
 | 
 | ||||||
|   >>> cc2 = Concept(u'Zope 3') |   >>> cc2 = Concept(u'Zope 3') | ||||||
|   >>> concepts['cc2'] = cc2 |   >>> concepts['cc2'] = cc2 | ||||||
|  | @ -277,13 +279,17 @@ target may be moved or renamed without any problems.) | ||||||
|   >>> nodeConfig = INodeConfigSchema(m111) |   >>> nodeConfig = INodeConfigSchema(m111) | ||||||
| 
 | 
 | ||||||
|   >>> nodeConfig.targetUri |   >>> nodeConfig.targetUri | ||||||
|   u'.loops/concepts/cc2' |   '.loops/concepts/cc2' | ||||||
|   >>> nodeConfig.title = u'New title for m111' |   >>> nodeConfig.title = u'New title for m111' | ||||||
|   >>> nodeConfig.title |   >>> nodeConfig.title | ||||||
|   u'New title for m111' |   u'New title for m111' | ||||||
|   >>> m111.title |   >>> m111.title | ||||||
|   u'New title for m111' |   u'New title for m111' | ||||||
|   >>> nodeConfig.targetUri = '.loops/resources/doc1' |   >>> nodeConfig.targetUri = '.loops/resources/doc1' | ||||||
|  | 
 | ||||||
|  | We have to get a new adapter to avoid problems with lazy variables: | ||||||
|  | 
 | ||||||
|  |   >>> nodeConfig = INodeConfigSchema(m111) | ||||||
|   >>> nodeConfig.title = 'New title for m111' |   >>> nodeConfig.title = 'New title for m111' | ||||||
|   >>> m111.target is doc1 |   >>> m111.target is doc1 | ||||||
|   True |   True | ||||||
|  | @ -305,11 +311,21 @@ application uses a subclass that does all the other stuff for form handling.) | ||||||
|   >>> form = {'field.createTarget': True, |   >>> form = {'field.createTarget': True, | ||||||
|   ...         'field.targetUri': '.loops/resources/ma07', |   ...         'field.targetUri': '.loops/resources/ma07', | ||||||
|   ...         'field.targetType': 'loops.resource.MediaAsset'} |   ...         'field.targetType': 'loops.resource.MediaAsset'} | ||||||
|   >>> view = ConfigureBaseView(INodeConfigSchema(m111), TestRequest(form=form)) |  | ||||||
|   >>> view = ConfigureBaseView(m111, TestRequest(form=form)) |   >>> view = ConfigureBaseView(m111, TestRequest(form=form)) | ||||||
|   >>> view.checkCreateTarget() |   >>> m111.target = view.checkCreateTarget() | ||||||
|   >>> sorted(resources.keys()) |   >>> sorted(resources.keys()) | ||||||
|   [u'doc1', u'ma07'] |   [u'doc1', u'ma07'] | ||||||
|  |   >>> isinstance(resources['ma07'], MediaAsset) | ||||||
|  |   True | ||||||
|  |    | ||||||
|  |   >>> form = {'field.createTarget': True, | ||||||
|  |   ...         'field.targetType': 'loops.resource.Document'} | ||||||
|  |   >>> view = ConfigureBaseView(m111, TestRequest(form=form)) | ||||||
|  |   >>> m111.target = view.checkCreateTarget() | ||||||
|  |   >>> sorted(resources.keys()) | ||||||
|  |   [u'doc1', u'm1.m11.m111', u'ma07'] | ||||||
|  |   >>> isinstance(resources['m1.m11.m111'], Document) | ||||||
|  |   True | ||||||
|          |          | ||||||
| It is also possible to edit a target's attributes directly in an | It is also possible to edit a target's attributes directly in an | ||||||
| edit form provided by the node: | edit form provided by the node: | ||||||
|  | @ -318,6 +334,11 @@ edit form provided by the node: | ||||||
|   >>> ztapi.provideAdapter(INode, IDocument, DocumentProxy) |   >>> ztapi.provideAdapter(INode, IDocument, DocumentProxy) | ||||||
|   >>> ztapi.provideAdapter(INode, IMediaAsset, MediaAssetProxy) |   >>> ztapi.provideAdapter(INode, IMediaAsset, MediaAssetProxy) | ||||||
| 
 | 
 | ||||||
|  |   >>> proxy = zapi.getAdapter(m111, IDocument) | ||||||
|  |   >>> proxy.title = u'Set via proxy' | ||||||
|  |   >>> resources['m1.m11.m111'].title | ||||||
|  |   u'Set via proxy' | ||||||
|  | 
 | ||||||
| Ordering Nodes | Ordering Nodes | ||||||
| -------------- | -------------- | ||||||
| 
 | 
 | ||||||
|  | @ -335,10 +356,10 @@ to the bottom, and to the top | ||||||
|        |        | ||||||
|   >>> from cybertools.container.ordered import OrderedContainerView |   >>> from cybertools.container.ordered import OrderedContainerView | ||||||
|   >>> view = OrderedContainerView(m11, TestRequest()) |   >>> view = OrderedContainerView(m11, TestRequest()) | ||||||
|   >>> view.moveToBottom(('m113',)) |   >>> view.move_bottom(('m113',)) | ||||||
|   >>> m11.keys() |   >>> m11.keys() | ||||||
|   ['m111', 'm112', 'm114', 'm113'] |   ['m111', 'm112', 'm114', 'm113'] | ||||||
|   >>> view.moveUp(('m114',), 1) |   >>> view.move_up(('m114',), 1) | ||||||
|   >>> m11.keys() |   >>> m11.keys() | ||||||
|   ['m111', 'm114', 'm112', 'm113'] |   ['m111', 'm114', 'm112', 'm113'] | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,8 +23,9 @@ | ||||||
| $Id$ | $Id$ | ||||||
| """ | """ | ||||||
| 
 | 
 | ||||||
| from zope.interface import implements | from zope.app import zapi | ||||||
| from zope.app.folder.folder import Folder | from zope.app.folder.folder import Folder | ||||||
|  | from zope.interface import implements | ||||||
| from interfaces import ILoops | from interfaces import ILoops | ||||||
| 
 | 
 | ||||||
| class Loops(Folder): | class Loops(Folder): | ||||||
|  | @ -34,3 +35,9 @@ class Loops(Folder): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return self |         return self | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self['views'] | ||||||
|  | 
 | ||||||
|  |     def getLoopsUri(self, obj): | ||||||
|  |         return str('.loops' + zapi.getPath(obj)[len(zapi.getPath(self)):]) | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -247,7 +247,6 @@ | ||||||
|   <containerViews |   <containerViews | ||||||
|       for="loops.interfaces.IViewManager" |       for="loops.interfaces.IViewManager" | ||||||
|       index="zope.ManageContent" |       index="zope.ManageContent" | ||||||
|       contents="zope.ManageContent" |  | ||||||
|       add="zope.ManageContent" |       add="zope.ManageContent" | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|  | @ -274,6 +273,7 @@ | ||||||
|       content_factory="loops.view.Node" |       content_factory="loops.view.Node" | ||||||
|       schema="loops.interfaces.INodeConfigSchema" |       schema="loops.interfaces.INodeConfigSchema" | ||||||
|       fields="title description nodeType targetType targetUri createTarget" |       fields="title description nodeType targetType targetUri createTarget" | ||||||
|  |       class="loops.browser.node.ConfigureView" | ||||||
|       permission="zope.ManageContent"> |       permission="zope.ManageContent"> | ||||||
|        |        | ||||||
|     <widget field="description" height="2" /> |     <widget field="description" height="2" /> | ||||||
|  | @ -304,6 +304,12 @@ | ||||||
| 
 | 
 | ||||||
|   </editform> |   </editform> | ||||||
| 
 | 
 | ||||||
|  |   <containerViews | ||||||
|  |       for="loops.interfaces.INode" | ||||||
|  |       index="zope.ManageContent" | ||||||
|  |       add="zope.ManageContent" | ||||||
|  |       /> | ||||||
|  | 
 | ||||||
|   <editform |   <editform | ||||||
|       label="Configure Node" |       label="Configure Node" | ||||||
|       name="configure.html" |       name="configure.html" | ||||||
|  | @ -320,6 +326,21 @@ | ||||||
| 
 | 
 | ||||||
|   </editform> |   </editform> | ||||||
| 
 | 
 | ||||||
|  |   <editform | ||||||
|  |       label="Edit Target" | ||||||
|  |       name="edit_target.html" | ||||||
|  |       schema="loops.interfaces.IMediaAsset" | ||||||
|  |       fields="title data contentType" | ||||||
|  |       for="loops.interfaces.INode" | ||||||
|  |       permission="zope.ManageContent" | ||||||
|  |       /> | ||||||
|  | 
 | ||||||
|  |   <menuItem | ||||||
|  |       for="loops.interfaces.INode" | ||||||
|  |       menu="zmi_views" action="edit_target.html" title="Edit Target" | ||||||
|  |       filter="context/target" | ||||||
|  |       /> | ||||||
|  |    | ||||||
|   <page |   <page | ||||||
|       name="node.html" |       name="node.html" | ||||||
|       for="loops.interfaces.INode" |       for="loops.interfaces.INode" | ||||||
|  | @ -333,10 +354,4 @@ | ||||||
|       name="node.html" |       name="node.html" | ||||||
|       /> |       /> | ||||||
| 
 | 
 | ||||||
|   <containerViews |  | ||||||
|       for="loops.interfaces.IBaseNode" |  | ||||||
|       index="zope.ManageContent" |  | ||||||
|       add="zope.ManageContent" |  | ||||||
|       /> |  | ||||||
| 
 |  | ||||||
| </configure> | </configure> | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ from zope.cachedescriptors.property import Lazy | ||||||
| from zope.app import zapi | from zope.app import zapi | ||||||
| from zope.app.container.browser.contents import JustContents | from zope.app.container.browser.contents import JustContents | ||||||
| from zope.app.dublincore.interfaces import ICMFDublinCore | from zope.app.dublincore.interfaces import ICMFDublinCore | ||||||
|  | from zope.configuration.config import ConfigurationContext | ||||||
| from zope.proxy import removeAllProxies | from zope.proxy import removeAllProxies | ||||||
| from zope.security import canAccess, canWrite | from zope.security import canAccess, canWrite | ||||||
| from zope.security.proxy import removeSecurityProxy | from zope.security.proxy import removeSecurityProxy | ||||||
|  | @ -104,18 +105,41 @@ class ConfigureBaseView(object): | ||||||
|         self.context = removeSecurityProxy(context) |         self.context = removeSecurityProxy(context) | ||||||
|         self.request = request |         self.request = request | ||||||
| 
 | 
 | ||||||
|  |     @Lazy | ||||||
|  |     def loopsRoot(self): | ||||||
|  |         return self.context.getLoopsRoot() | ||||||
|  | 
 | ||||||
|     def checkCreateTarget(self): |     def checkCreateTarget(self): | ||||||
|         form = self.request.form |         form = self.request.form | ||||||
|         if 'field.createTarget' in form: |         if form.get('field.createTarget', False): | ||||||
|             type = self.request.form.get('field.targetType', |             type = self.request.form.get('field.targetType', | ||||||
|                                          'loops.resource.MediaAsset') |                                          'loops.resource.MediaAsset') | ||||||
|             # TODO: find class (better: factory) from type name |             factory = ConfigurationContext().resolve(type) | ||||||
|             uri = self.request.form.get('field.targetUri', None) |             uri = self.request.form.get('field.targetUri', None) | ||||||
|             # TODO: generate uri/__name__ if not given |  | ||||||
|             if uri: |             if uri: | ||||||
|                 # TODO: find container |                 path = uri.split('/') | ||||||
|                 self.context.getLoopsRoot()['resources']['ma07'] = MediaAsset() |                 containerName = path[-2] | ||||||
|                 #self.context.loopsRoot['resources']['ma07'] = MediaAsset() |                 name = path[-1] | ||||||
|  |             else: | ||||||
|  |                 containerName = 'resource' in type and 'resources' or 'concepts' | ||||||
|  |                 viewManagerPath = zapi.getPath(self.context.getViewManager()) | ||||||
|  |                 name = zapi.getPath(self.context)[len(viewManagerPath)+1:] | ||||||
|  |                 name = name.replace('/', '.') | ||||||
|  |             container = self.loopsRoot[containerName] | ||||||
|  |             # check for duplicates: | ||||||
|  |             num = 1 | ||||||
|  |             basename = name | ||||||
|  |             while name in container: | ||||||
|  |                 name = '%s-%d' % (basename, num) | ||||||
|  |                 num += 1 | ||||||
|  |             # create target: | ||||||
|  |             container[name] = factory() | ||||||
|  |             target = container[name] | ||||||
|  |             # set possibly new targetUri in request for further processing: | ||||||
|  |             targetUri = self.loopsRoot.getLoopsUri(target) | ||||||
|  |             form['field.targetUri'] = targetUri | ||||||
|  |             return target | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class ConfigureView(object): | class ConfigureView(object): | ||||||
|     """ An editing view for configuring a node, optionally creating |     """ An editing view for configuring a node, optionally creating | ||||||
|  |  | ||||||
|  | @ -65,6 +65,9 @@ class Concept(Contained, Persistent): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self).getLoopsRoot() |         return zapi.getParent(self).getLoopsRoot() | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self.getLoopsRoot().getViewManager() | ||||||
|  | 
 | ||||||
|     # concept relations |     # concept relations | ||||||
| 
 | 
 | ||||||
|     def getSubConcepts(self, relationships=None): |     def getSubConcepts(self, relationships=None): | ||||||
|  | @ -128,3 +131,8 @@ class ConceptManager(BTreeContainer): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self) |         return zapi.getParent(self) | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self.getLoopsRoot().getViewManager() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |      | ||||||
|  |  | ||||||
|  | @ -218,8 +218,10 @@ | ||||||
|   <adapter factory=".view.NodeConfigAdapter" |   <adapter factory=".view.NodeConfigAdapter" | ||||||
|            permission="zope.ManageContent" /> |            permission="zope.ManageContent" /> | ||||||
| 
 | 
 | ||||||
|   <adapter factory="loops.target.DocumentProxy" /> |   <adapter factory="loops.target.DocumentProxy" | ||||||
|   <adapter factory="loops.target.MediaAssetProxy" /> |            permission="zope.ManageContent" /> | ||||||
|  |   <adapter factory="loops.target.MediaAssetProxy" | ||||||
|  |            permission="zope.ManageContent" /> | ||||||
| 
 | 
 | ||||||
|   <view factory="loops.view.NodeTraverser" |   <view factory="loops.view.NodeTraverser" | ||||||
|         for="loops.interfaces.INode" |         for="loops.interfaces.INode" | ||||||
|  |  | ||||||
|  | @ -43,6 +43,10 @@ class ILoopsObject(Interface): | ||||||
|         """ Return the loops root object. |         """ Return the loops root object. | ||||||
|         """ |         """ | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(): | ||||||
|  |         """ Return the (default) view manager. | ||||||
|  |         """ | ||||||
|  | 
 | ||||||
| # concept interfaces | # concept interfaces | ||||||
| 
 | 
 | ||||||
| class IConcept(ILoopsObject): | class IConcept(ILoopsObject): | ||||||
|  | @ -311,6 +315,10 @@ class ILoops(ILoopsObject, IFolder): | ||||||
|     """ |     """ | ||||||
|     contains(IConceptManager, IResourceManager, IViewManager) |     contains(IConceptManager, IResourceManager, IViewManager) | ||||||
| 
 | 
 | ||||||
|  |     def getLoopsUri(obj): | ||||||
|  |         """ Return the relativ path to obj, starting with '.loops/...'. | ||||||
|  |         """ | ||||||
|  |      | ||||||
| 
 | 
 | ||||||
| class ILoopsContained(Interface): | class ILoopsContained(Interface): | ||||||
|     containers(ILoops) |     containers(ILoops) | ||||||
|  |  | ||||||
|  | @ -55,6 +55,9 @@ class Resource(Contained, Persistent): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self).getLoopsRoot() |         return zapi.getParent(self).getLoopsRoot() | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self.getLoopsRoot().getViewManager() | ||||||
|  | 
 | ||||||
|     def getClients(self, relationships=None): |     def getClients(self, relationships=None): | ||||||
|         rels = getRelations(second=self, relationships=relationships) |         rels = getRelations(second=self, relationships=relationships) | ||||||
|         return [r.first for r in rels] |         return [r.first for r in rels] | ||||||
|  | @ -105,4 +108,8 @@ class ResourceManager(BTreeContainer): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self) |         return zapi.getParent(self) | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self.getLoopsRoot().getViewManager() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ from zope.app import zapi | ||||||
| from zope.cachedescriptors.property import Lazy | from zope.cachedescriptors.property import Lazy | ||||||
| from zope.component import adapts | from zope.component import adapts | ||||||
| from zope.interface import implements | from zope.interface import implements | ||||||
|  | from zope.security.proxy import removeSecurityProxy | ||||||
| 
 | 
 | ||||||
| from loops.interfaces import IResource, IDocument, IMediaAsset | from loops.interfaces import IResource, IDocument, IMediaAsset | ||||||
| from loops.interfaces import IView | from loops.interfaces import IView | ||||||
|  | @ -37,16 +38,17 @@ class ResourceProxy(object): | ||||||
|     adapts(IView) |     adapts(IView) | ||||||
| 
 | 
 | ||||||
|     def getTitle(self): return self.target.title |     def getTitle(self): return self.target.title | ||||||
|     def setTitle(self, title): self.title = title |     def setTitle(self, title): self.target.title = title | ||||||
|     title = property(getTitle, setTitle) |     title = property(getTitle, setTitle) | ||||||
| 
 | 
 | ||||||
|     def setContentType(self, contentType): |     def setContentType(self, contentType): | ||||||
|         self.target._contentType = contentType |         self.target.contentType = contentType | ||||||
|     def getContentType(self): return self.target.contentType |     def getContentType(self): return self.target.contentType | ||||||
|     contentType = property(getContentType, setContentType) |     contentType = property(getContentType, setContentType) | ||||||
| 
 | 
 | ||||||
|     def __init__(self, context): |     def __init__(self, context): | ||||||
|         self.context = context |         self.context = context | ||||||
|  |         #self.context = removeSecurityProxy(context) | ||||||
| 
 | 
 | ||||||
|     @Lazy |     @Lazy | ||||||
|     def target(self): |     def target(self): | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								view.py
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								view.py
									
										
									
									
									
								
							|  | @ -60,7 +60,8 @@ class View(object): | ||||||
|         if len(rels) == 0: |         if len(rels) == 0: | ||||||
|             return None |             return None | ||||||
|         if len(rels) > 1: |         if len(rels) > 1: | ||||||
|             raise ValueError, 'There may be only one target for a View object.' |             raise ValueError('There may be only one target for a View object: %s - %s' | ||||||
|  |                 % (zapi.getName(self), `[zapi.getName(r.second) for r in rels]`)) | ||||||
|         return list(rels)[0].second |         return list(rels)[0].second | ||||||
| 
 | 
 | ||||||
|     def setTarget(self, target): |     def setTarget(self, target): | ||||||
|  | @ -72,6 +73,7 @@ class View(object): | ||||||
|                 return |                 return | ||||||
|             else: |             else: | ||||||
|                 registry.unregister(oldRel) |                 registry.unregister(oldRel) | ||||||
|  |         if target: | ||||||
|             rel = TargetRelation(self, target) |             rel = TargetRelation(self, target) | ||||||
|             registry.register(rel) |             registry.register(rel) | ||||||
| 
 | 
 | ||||||
|  | @ -85,6 +87,9 @@ class View(object): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self).getLoopsRoot() |         return zapi.getParent(self).getLoopsRoot() | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return zapi.getParent(self).getViewManager() | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class Node(View, OrderedContainer): | class Node(View, OrderedContainer): | ||||||
| 
 | 
 | ||||||
|  | @ -141,6 +146,9 @@ class ViewManager(OrderedContainer): | ||||||
|     def getLoopsRoot(self): |     def getLoopsRoot(self): | ||||||
|         return zapi.getParent(self) |         return zapi.getParent(self) | ||||||
| 
 | 
 | ||||||
|  |     def getViewManager(self): | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| class TargetRelation(DyadicRelation): | class TargetRelation(DyadicRelation): | ||||||
|     """ A relation between a view and another object. |     """ A relation between a view and another object. | ||||||
|  | @ -186,24 +194,30 @@ class NodeConfigAdapter(object): | ||||||
|     @Lazy |     @Lazy | ||||||
|     def loopsRoot(self): return self.context.getLoopsRoot() |     def loopsRoot(self): return self.context.getLoopsRoot() | ||||||
| 
 | 
 | ||||||
|  |     @Lazy | ||||||
|  |     def target(self): | ||||||
|  |         return self.context.target | ||||||
|  | 
 | ||||||
|     def getTargetUri(self): |     def getTargetUri(self): | ||||||
|         rootPath = zapi.getPath(self.loopsRoot) |         target = self.target | ||||||
|         if self.context.target is not None: |         if target is not None: | ||||||
|             path = zapi.getPath(self.context.target)[len(rootPath):] |             return self.loopsRoot.getLoopsUri(target) | ||||||
|             return '.loops' + path |  | ||||||
|         else: |         else: | ||||||
|             return '' |             return '' | ||||||
|      |      | ||||||
|     def setTargetUri(self, uri): |     def setTargetUri(self, uri): | ||||||
|  |         if uri: | ||||||
|             names = uri.split('/') |             names = uri.split('/') | ||||||
|             if names[0] == '.loops': |             if names[0] == '.loops': | ||||||
|                 path = '/'.join(names[1:]) |                 path = '/'.join(names[1:]) | ||||||
|                 self.context.target = zapi.traverse(self.loopsRoot, path) |                 self.context.target = zapi.traverse(self.loopsRoot, path) | ||||||
|  |         else: | ||||||
|  |             self.context.target = None | ||||||
|              |              | ||||||
|     targetUri = property(getTargetUri, setTargetUri) |     targetUri = property(getTargetUri, setTargetUri) | ||||||
| 
 | 
 | ||||||
|     def getTargetType(self): |     def getTargetType(self): | ||||||
|         target = self.context.target |         target = self.target | ||||||
|         if target: |         if target: | ||||||
|             return '%s.%s' % (target.__module__, target.__class__.__name__) |             return '%s.%s' % (target.__module__, target.__class__.__name__) | ||||||
|         return None |         return None | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 helmutm
						helmutm