diff -r 000000000000 -r 7c0001cacf8e src/pyams_content/component/paragraph/container.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_content/component/paragraph/container.py Thu Oct 08 13:37:29 2015 +0200 @@ -0,0 +1,71 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_content.component.paragraph.interfaces import IParagraphContainer, IParagraphContainerTarget, \ + PARAGRAPH_CONTAINER_KEY +from zope.annotation.interfaces import IAnnotations +from zope.location.interfaces import ISublocations +from zope.traversing.interfaces import ITraversable + +# import packages +from pyams_utils.adapter import adapter_config, ContextAdapter +from pyams_utils.container import BTreeOrderedContainer +from pyramid.threadlocal import get_current_registry +from zope.interface import implementer +from zope.lifecycleevent import ObjectCreatedEvent +from zope.location import locate + + +@implementer(IParagraphContainer) +class ParagraphContainer(BTreeOrderedContainer): + """Paragraphs container""" + + last_id = 1 + + def __setitem__(self, key, value): + key = str(self.last_id) + super(ParagraphContainer, self).__setitem__(key, value) + self.last_id += 1 + + +@adapter_config(context=IParagraphContainerTarget, provides=IParagraphContainer) +def paragraph_container_factory(target): + """Paragraphs container factory""" + annotations = IAnnotations(target) + container = annotations.get(PARAGRAPH_CONTAINER_KEY) + if container is None: + container = annotations[PARAGRAPH_CONTAINER_KEY] = ParagraphContainer() + get_current_registry().notify(ObjectCreatedEvent(container)) + locate(container, target, '++paras++') + return container + + +@adapter_config(name='paras', context=IParagraphContainerTarget, provides=ITraversable) +class ParagraphContainerNamespace(ContextAdapter): + """++paras++ namespace adapter""" + + def traverse(self, name, furtherpath=None): + return IParagraphContainer(self.context) + + +@adapter_config(name='paras', context=IParagraphContainerTarget, provides=ISublocations) +class ParagraphContainerSublocations(ContextAdapter): + """Paragraphs container sublocations""" + + def sublocations(self): + return IParagraphContainer(self.context).values()