diff --git a/README.txt b/README.txt
index 3dfe836..ed5f501 100755
--- a/README.txt
+++ b/README.txt
@@ -837,52 +837,11 @@ informations about all parents of an object.
Import/Export
=============
-Nodes may be exported to and loaded from external sources, typically
-file representations that allow the transfer of nodes from one Zope
-instance to another.
-
- >>> from loops.external import NodesLoader
- >>> loader = NodesLoader(views)
- >>> data = [{'name': 'm2', 'path': '', 'description': u'desc 1',
- ... 'title': u'M 2', 'body': u'test m2', 'nodeType': 'menu' },
- ... {'name': 'm21', 'path': 'm2', 'description': u'',
- ... 'title': u'M 21', 'body': u'test m21', 'nodeType': 'page' },
- ... {'name': 'm114', 'path': 'm1/m11', 'description': u'',
- ... 'title': u'M 114', 'body': u'test m114', 'nodeType': 'page' },]
- >>> loader.load(data)
- >>> views['m2']['m21'].title
- u'M 21'
- >>> views['m1']['m11']['m114'].title
- u'M 114'
-
- >>> from loops.external import NodesExporter, NodesImporter
- >>> exporter = NodesExporter(views)
- >>> data = exporter.extractData()
- >>> len(data)
- 8
- >>> data[3]['path']
- u'm1/m11'
- >>> data[3]['name']
- u'm112'
-
- >>> dumpname = os.path.dirname(__file__) + '/test.tmp'
- >>> exporter.filename = dumpname
- >>> exporter.dumpData()
-
-Load them again from the exported file:
-
- >>> importer = NodesImporter(views)
- >>> importer.filename = dumpname
- >>> imported = importer.getData()
- >>> imported == data
- True
-
- >>> loader.load(imported)
+Obsolete - see package loops.external.
Fin de partie
=============
- >>> os.unlink(dumpname)
>>> placefulTearDown()
diff --git a/browser/configure.zcml b/browser/configure.zcml
index 1176ebe..4108841 100644
--- a/browser/configure.zcml
+++ b/browser/configure.zcml
@@ -391,20 +391,16 @@
menu="zmi_views" title="Contents"
/>
-
-
+
diff --git a/configure.zcml b/configure.zcml
index c76f812..ef93674 100644
--- a/configure.zcml
+++ b/configure.zcml
@@ -325,9 +325,11 @@
+
+
diff --git a/external/README.txt b/external/README.txt
index 1e55046..c4a7761 100644
--- a/external/README.txt
+++ b/external/README.txt
@@ -48,6 +48,16 @@ Creating the corresponding objects
>>> adapted(concepts['myquery']).viewName
'mystuff.html'
+Working with nodes
+------------------
+
+ >>> input = ("node('home', u'Home', '', u'menu', body=u'Welcome')\n"
+ ... "node('myquery', u'My Query', 'home', u'page', "
+ ... " target='concepts/myquery')")
+ >>> reader = PyReader()
+ >>> elements = reader.read(input)
+ >>> loader.load(elements)
+
Exporting loops Objects
=======================
@@ -60,7 +70,7 @@ Extracting elements
>>> extractor = Extractor(loopsRoot)
>>> elements = list(extractor.extract())
>>> len(elements)
- 13
+ 15
Writing object information to the external storage
--------------------------------------------------
@@ -76,7 +86,9 @@ Writing object information to the external storage
type(u'query', u'Query', options=u'', typeInterface='loops.query.IQueryConcept',
viewName=u'')...
concept(u'myquery', u'My Query', u'query', options=u'', viewName='mystuff.html')...
- child(u'projects', u'customer', u'standard')...
+ child(u'projects', u'customer', u'standard')
+ node('home', u'Home', '', u'menu', body=u'Welcome')
+ node('myquery', u'My Query', 'home', u'page', target=u'concepts/myquery')...
The Export/Import View
diff --git a/external/__init__.py b/external/__init__.py
index 1b17f2a..ea79f84 100644
--- a/external/__init__.py
+++ b/external/__init__.py
@@ -2,4 +2,4 @@
$Id$
"""
-from loops.external.external import NodesLoader, NodesExporter, NodesImporter
+#from loops.external.external import NodesLoader, NodesExporter, NodesImporter
diff --git a/external/base.py b/external/base.py
index 914f676..b8dec5e 100644
--- a/external/base.py
+++ b/external/base.py
@@ -28,7 +28,7 @@ import itertools
from zope import component
from zope.cachedescriptors.property import Lazy
from zope.interface import implements
-from zope.traversing.api import getName
+from zope.traversing.api import getName, getParent
from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.interfaces import ISchemaFactory
@@ -49,6 +49,14 @@ class Base(object):
def concepts(self):
return self.context.getConceptManager()
+ @Lazy
+ def resources(self):
+ return self.context.getResourceManager()
+
+ @Lazy
+ def views(self):
+ return self.context.getViewManager()
+
@Lazy
def typeConcept(self):
return self.concepts.getTypeConcept()
@@ -84,8 +92,7 @@ class Extractor(Base):
self.extractChildren(),
#self.extractResources(),
#self.extractResourceRelations(),
- #self.extractNodes(),
- #self.extractTargets(),
+ self.extractNodes(),
)
def extractTypes(self):
@@ -141,3 +148,21 @@ class Extractor(Base):
args.append(r.relevance)
yield childElement(*args)
+ def extractNodes(self, parent=None, path=''):
+ if parent is None:
+ parent = self.views
+ element = elementTypes['node']
+ for name, obj in parent.items():
+ data = {}
+ for attr in ('description', 'body', 'viewName'):
+ value = getattr(obj, attr)
+ if value:
+ data[attr] = value
+ target = obj.target
+ if target is not None:
+ data['target'] = '/'.join((getName(getParent(target)), getName(target)))
+ yield element(name, obj.title, path, obj.nodeType, **data)
+ childPath = path and '/'.join((path, name)) or name
+ for elem in self.extractNodes(obj, childPath):
+ yield elem
+
diff --git a/external/element.py b/external/element.py
index 150d2ec..25f7ffb 100644
--- a/external/element.py
+++ b/external/element.py
@@ -26,7 +26,7 @@ $Id$
from zope.cachedescriptors.property import Lazy
from zope.dottedname.resolve import resolve
from zope.interface import implements
-from zope.traversing.api import getName
+from zope.traversing.api import getName, traverse
from loops.external.interfaces import IElement
@@ -57,7 +57,7 @@ class ConceptElement(Element):
def __call__(self, loader):
type = loader.concepts[self['type']]
kw = dict((k, v) for k, v in self.items()
- if k not in ('name', 'title', 'type'))
+ if k not in self.posArgs)
loader.addConcept(self['name'], self['title'], type, **kw)
@@ -81,11 +81,6 @@ class TypeElement(ConceptElement):
loader.addConcept(self['name'], self['title'], 'type', **kw)
-class ResourceElement(ConceptElement):
-
- elementType = 'resource'
-
-
class ChildElement(Element):
elementType = 'child'
@@ -99,9 +94,56 @@ class ChildElement(Element):
loader.assignChild(self['first'], self['second'], self['predicate'])
+class NodeElement(Element):
+
+ elementType = 'node'
+ posArgs = ('name', 'title', 'path', 'type')
+
+ def __init__(self, *args, **kw):
+ for idx, arg in enumerate(args):
+ self[self.posArgs[idx]] = arg
+ for k, v in kw.items():
+ self[k] = v
+
+ def __call__(self, loader):
+ type = self['type']
+ cont = traverse(loader.views, self['path'])
+ target = self.pop('target', None)
+ kw = dict((k, v) for k, v in self.items()
+ if k not in self.posArgs)
+ node = loader.addNode(self['name'], self['title'], cont, type, **kw)
+ if target is not None:
+ node.target = traverse(loader.context, target)
+
+
+# not yet implemented
+
+class ResourceElement(Element):
+
+ elementType = 'resource'
+ posArgs = ('name', 'title', 'type')
+
+ def __call__(self, loader):
+ type = loader.concepts[self['type']]
+ kw = dict((k, v) for k, v in self.items()
+ if k not in self.posArgs)
+ loader.addResource(self['name'], self['title'], type, **kw)
+
+
+class ResourceRelationElement(ChildElement):
+
+ elementType = 'resourceRelation'
+
+ def __call__(self, loader):
+ loader.assignResource(self['first'], self['second'], self['predicate'])
+
+
+# element registry
+
elementTypes = dict(
type=TypeElement,
concept=ConceptElement,
resource=ResourceElement,
child=ChildElement,
+ node=NodeElement,
)
diff --git a/external/external.py b/external/external.py
index 80851c0..6d7381a 100644
--- a/external/external.py
+++ b/external/external.py
@@ -19,6 +19,8 @@
"""
Adapter implementations for export, import, ...
+Obsolete, replaced by functionality in loops.external.base and other modules
+
$Id$
"""