Updated typed shared contents management
authorThierry Florac <tflorac@ulthar.net>
Tue, 19 Nov 2019 16:39:10 +0100
changeset 1384 cdf63a1c7dc9
parent 1383 2cfeb340dacf
child 1385 7383e6ce5411
Updated typed shared contents management
src/pyams_content/shared/common/interfaces/types.py
src/pyams_content/shared/common/types.py
src/pyams_content/shared/common/zmi/summary.py
src/pyams_content/shared/common/zmi/types/__init__.py
src/pyams_content/shared/common/zmi/types/manager.py
src/pyams_content/shared/common/zmi/types/summary.py
src/pyams_content/shared/resource/__init__.py
src/pyams_content/shared/resource/interfaces.py
src/pyams_content/shared/resource/manager.py
src/pyams_content/shared/resource/zmi/widget.py
src/pyams_content/shared/site/__init__.py
src/pyams_content/shared/site/interfaces.py
src/pyams_content/shared/site/manager.py
src/pyams_content/shared/site/zmi/__init__.py
src/pyams_content/shared/site/zmi/container.py
src/pyams_content/shared/site/zmi/summary.py
src/pyams_content/shared/topic/__init__.py
src/pyams_content/shared/topic/interfaces.py
src/pyams_content/shared/topic/manager.py
src/pyams_content/shared/topic/zmi/summary.py
--- a/src/pyams_content/shared/common/interfaces/types.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/common/interfaces/types.py	Tue Nov 19 16:39:10 2019 +0100
@@ -12,13 +12,13 @@
 
 from zope.container.constraints import contains
 from zope.container.interfaces import IContainer
-from zope.interface import Attribute
+from zope.interface import Attribute, Interface
 from zope.location.interfaces import ILocation
 from zope.schema import Bool, Choice, List, TextLine
 
 from pyams_content.reference.pictograms.interfaces import PICTOGRAM_VOCABULARY
-from pyams_content.shared.common.interfaces import IBaseContentPortalContext, ISharedTool, \
-    IWfSharedContent
+from pyams_content.shared.common import IWfSharedContent
+from pyams_content.shared.common.interfaces import IBaseContentPortalContext
 from pyams_i18n.schema import I18nTextLineField
 from pyams_portal.interfaces import IPortalContext
 from pyams_sequence.schema import InternalReferenceField
@@ -100,7 +100,7 @@
     contains(IDataType)
 
 
-class ITypedSharedTool(ISharedTool):
+class ITypedSharedTool(Interface):
     """Shared tool containing typed data"""
 
     shared_content_types_fields = Attribute("Content fields interface")
--- a/src/pyams_content/shared/common/types.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/common/types.py	Tue Nov 19 16:39:10 2019 +0100
@@ -87,7 +87,7 @@
 
 
 @implementer(ITypedSharedTool)
-class TypedSharedTool(SharedTool):
+class TypedSharedToolMixin(object):
     """Typed shared tool"""
 
     shared_content_types_fields = None
@@ -121,7 +121,7 @@
 #
 
 @implementer(IWfTypedSharedContent)
-class WfTypedSharedContent(WfSharedContent):
+class WfTypedSharedContentMixin(object):
     """Typed shared content"""
 
     data_type = FieldProperty(IWfTypedSharedContent['data_type'])
--- a/src/pyams_content/shared/common/zmi/summary.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/common/zmi/summary.py	Tue Nov 19 16:39:10 2019 +0100
@@ -73,10 +73,8 @@
 
     @property
     def fields(self):
-        fields = field.Fields(IWfSharedContent).select('title')
-        if IWfTypedSharedContent.providedBy(self.context):
-            fields += field.Fields(IWfTypedSharedContent).select('data_type')
-        fields += field.Fields(ISequentialIdInfo).select('public_oid')
+        fields = field.Fields(IWfSharedContent).select('title') + \
+                 field.Fields(ISequentialIdInfo).select('public_oid')
         return fields
 
 
--- a/src/pyams_content/shared/common/zmi/types/__init__.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/common/zmi/types/__init__.py	Tue Nov 19 16:39:10 2019 +0100
@@ -23,6 +23,7 @@
 
 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION, MANAGE_TOOL_PERMISSION
 from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
+from pyams_content.shared.common import IWfSharedContent
 from pyams_content.shared.common.interfaces.types import IBaseDataType, IDataType, ISubType, \
     ITypedDataManager, ITypedSharedTool, IWfTypedSharedContent
 from pyams_content.shared.common.types import DataType, SubType
@@ -395,7 +396,9 @@
 class TypedSharedContentAddForm(SharedContentAddForm):
     """Typed shared content add form"""
 
-    fields = field.Fields(IWfTypedSharedContent).select('title', 'data_type', 'notepad')
+    fields = field.Fields(IWfSharedContent).select('title') + \
+             field.Fields(IWfTypedSharedContent).select('data_type') + \
+             field.Fields(IWfSharedContent).select('notepad')
 
     def updateWidgets(self, prefix=None):
         super(TypedSharedContentAddForm, self).updateWidgets(prefix)
--- a/src/pyams_content/shared/common/zmi/types/manager.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/common/zmi/types/manager.py	Tue Nov 19 16:39:10 2019 +0100
@@ -83,7 +83,7 @@
 
     @reify
     def values(self):
-        return list(super(TypedSharedToolTypesTable, self).values)
+        return list(ITypedDataManager(self.context).values())
 
     def render(self):
         if not self.values:
@@ -92,15 +92,6 @@
         return super(TypedSharedToolTypesTable, self).render()
 
 
-@adapter_config(context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable), provides=IValues)
-class TypedSharedToolTypesValues(ContextRequestViewAdapter):
-    """Typed shared tool types table values adapter"""
-
-    @property
-    def values(self):
-        return ITypedDataManager(self.context).values()
-
-
 @adapter_config(name='sorter', context=(ITypedSharedTool, IPyAMSLayer, TypedSharedToolTypesTable),
                 provides=IColumn)
 class TypedSharedToolTypesSorterColumn(ProtectedFormObjectMixin, SorterColumn):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/common/zmi/types/summary.py	Tue Nov 19 16:39:10 2019 +0100
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2008-2019 Thierry Florac <tflorac AT ulthar.net>
+# 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.
+#
+
+from z3c.form import field
+
+from pyams_content.shared.common import IWfSharedContent
+from pyams_content.shared.common.interfaces.types import IWfTypedSharedContent
+from pyams_content.shared.common.zmi.summary import SharedContentDublinCoreSummary, \
+    SharedContentSummaryForm
+from pyams_form.interfaces.form import IInnerTabForm
+from pyams_sequence.interfaces import ISequentialIdInfo
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.adapter import adapter_config
+
+
+__docformat__ = 'restructuredtext'
+
+
+@adapter_config(name='dublincore-summary',
+                context=(IWfTypedSharedContent, IPyAMSLayer, SharedContentSummaryForm),
+                provides=IInnerTabForm)
+class TypedSharedContentDublinCoreSummary(SharedContentDublinCoreSummary):
+    """Typed shared content DublinCore summary"""
+
+    @property
+    def fields(self):
+        fields = field.Fields(IWfSharedContent).select('title') + \
+                 field.Fields(IWfTypedSharedContent).select('data_type') + \
+                 field.Fields(ISequentialIdInfo).select('public_oid')
+        return fields
--- a/src/pyams_content/shared/resource/__init__.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/resource/__init__.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,31 +10,33 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from persistent import Persistent
 from zope.container.contained import Contained
 from zope.interface import implementer, provider
 from zope.schema.fieldproperty import FieldProperty
 
-from pyams_content.component.illustration.interfaces import IIllustrationTarget, ILinkIllustrationTarget
+from pyams_content.component.illustration.interfaces import IIllustrationTarget, \
+    ILinkIllustrationTarget
 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
 from pyams_content.component.theme.interfaces import ICollectionsTarget, ITagsTarget, IThemesTarget
 from pyams_content.features.preview.interfaces import IPreviewTarget
 from pyams_content.features.review.interfaces import IReviewTarget
-from pyams_content.shared.common import SharedContent, register_content_type
+from pyams_content.shared.common import SharedContent, WfSharedContent, register_content_type
 from pyams_content.shared.common.interfaces import IWfSharedContentFactory
-from pyams_content.shared.common.types import WfTypedSharedContent
-from pyams_content.shared.resource.interfaces import IResource, IResourceInfo, IWfResource, IWfResourceFactory, \
-    RESOURCE_CONTENT_NAME, RESOURCE_CONTENT_TYPE, RESOURCE_INFO_ANNOTATIONS_KEY
+from pyams_content.shared.common.types import WfTypedSharedContentMixin
+from pyams_content.shared.resource.interfaces import IResource, IResourceInfo, IWfResource, \
+    IWfResourceFactory, RESOURCE_CONTENT_NAME, RESOURCE_CONTENT_TYPE, RESOURCE_INFO_ANNOTATIONS_KEY
 from pyams_content.shared.resource.schema import IAgeRange
 from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from pyams_utils.factory import factory_config
 
 
+__docformat__ = 'restructuredtext'
+
+
 @implementer(IWfResource, IIllustrationTarget, ILinkIllustrationTarget, IParagraphContainerTarget,
              ITagsTarget, ICollectionsTarget, IThemesTarget, IPreviewTarget, IReviewTarget)
-class WfResource(WfTypedSharedContent):
+class WfResource(WfSharedContent, WfTypedSharedContentMixin):
     """Resource class"""
 
     content_type = RESOURCE_CONTENT_TYPE
--- a/src/pyams_content/shared/resource/interfaces.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/resource/interfaces.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,27 +10,29 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from datetime import datetime
 
 from zope.interface import Interface
 from zope.schema import Choice, Float, Int, TextLine, URI
 
-from pyams_content import _
 from pyams_content.shared.common import ISharedContent
-from pyams_content.shared.common.interfaces.types import ITypedSharedToolPortalContext, \
-    IWfTypedSharedContentPortalContext
+from pyams_content.shared.common.interfaces import ISharedToolPortalContext, \
+    IWfSharedContentPortalContext
 from pyams_content.shared.resource.schema import AgeRangeField
 from pyams_i18n.schema import I18nHTMLField, I18nTextField
 from pyams_sequence.interfaces import IInternalReferencesList
 
 
+__docformat__ = 'restructuredtext'
+
+from pyams_content import _
+
+
 RESOURCE_CONTENT_TYPE = 'resource'
 RESOURCE_CONTENT_NAME = _("Resource")
 
 
-class IResourceManager(ITypedSharedToolPortalContext):
+class IResourceManager(ISharedToolPortalContext):
     """Resource manager interface"""
 
 
@@ -38,7 +40,7 @@
     """Resource manager factory interface"""
 
 
-class IWfResource(IWfTypedSharedContentPortalContext, IInternalReferencesList):
+class IWfResource(IWfSharedContentPortalContext, IInternalReferencesList):
     """Resource content interface"""
 
 
--- a/src/pyams_content/shared/resource/manager.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/resource/manager.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,8 +10,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from pyramid.events import subscriber
 from zope.component.interfaces import ISite
 from zope.interface import implementer
@@ -22,7 +20,8 @@
 from pyams_content.component.theme import ICollectionsManagerTarget, IThemesManagerTarget
 from pyams_content.reference.pictograms.interfaces import IPictogramManagerTarget
 from pyams_content.shared.common.interfaces import ISharedContentFactory
-from pyams_content.shared.common.types import TypedSharedTool
+from pyams_content.shared.common.manager import SharedTool
+from pyams_content.shared.common.types import TypedSharedToolMixin
 from pyams_content.shared.resource import IResourceInfo, RESOURCE_CONTENT_TYPE, Resource
 from pyams_content.shared.resource.interfaces import IResourceManager, IResourceManagerFactory
 from pyams_utils.adapter import adapter_config
@@ -30,9 +29,12 @@
 from pyams_utils.traversing import get_parent
 
 
+__docformat__ = 'restructuredtext'
+
+
 @implementer(IResourceManager, IParagraphFactorySettings, IPictogramManagerTarget,
              IThemesManagerTarget, ICollectionsManagerTarget)
-class ResourceManager(TypedSharedTool):
+class ResourceManager(SharedTool, TypedSharedToolMixin):
     """Resource manager class"""
 
     shared_content_type = RESOURCE_CONTENT_TYPE
--- a/src/pyams_content/shared/resource/zmi/widget.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/resource/zmi/widget.py	Tue Nov 19 16:39:10 2019 +0100
@@ -47,7 +47,7 @@
 
     def updateWidgets(self, setErrors=True):
         super(AgeRangeWidget, self).updateWidgets(setErrors)
-        widgets = self.subform.widgets
+        widgets = self.widgets
         for name in ('min_value', 'max_value'):
             widget = widgets[name]
             widget.label_css_class = 'control-label col-md-2'
--- a/src/pyams_content/shared/site/__init__.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/site/__init__.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,8 +10,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from zope.interface import implementer, provider
 from zope.schema.fieldproperty import FieldProperty
 
@@ -20,22 +18,28 @@
 from pyams_content.component.theme.interfaces import ITagsTarget, IThemesTarget
 from pyams_content.features.preview.interfaces import IPreviewTarget
 from pyams_content.features.review.interfaces import IReviewTarget
-from pyams_content.shared.common import IWfSharedContentFactory, SharedContent, WfSharedContent, register_content_type
-from pyams_content.shared.site.interfaces import ISiteElementNavigation, ISiteTopic, IWfSiteTopic, IWfSiteTopicFactory, \
-    SITE_TOPIC_CONTENT_NAME, SITE_TOPIC_CONTENT_TYPE
+from pyams_content.shared.common import IWfSharedContentFactory, SharedContent, WfSharedContent, \
+    register_content_type
+from pyams_content.shared.common.types import WfTypedSharedContentMixin
+from pyams_content.shared.site.interfaces import ISiteElementNavigation, ISiteTopic, IWfSiteTopic, \
+    IWfSiteTopicFactory, SITE_TOPIC_CONTENT_NAME, SITE_TOPIC_CONTENT_TYPE
 from pyams_utils.adapter import adapter_config
 from pyams_workflow.interfaces import IWorkflow, IWorkflowState, IWorkflowVersions
 
 
+__docformat__ = 'restructuredtext'
+
+
 @implementer(IWfSiteTopic, IIllustrationTarget, ILinkIllustrationTarget, IParagraphContainerTarget,
              ITagsTarget, IThemesTarget, IPreviewTarget, IReviewTarget)
-class WfSiteTopic(WfSharedContent):
+class WfSiteTopic(WfSharedContent, WfTypedSharedContentMixin):
     """Base site topic"""
 
     content_type = SITE_TOPIC_CONTENT_TYPE
     content_name = SITE_TOPIC_CONTENT_NAME
 
     references = FieldProperty(IWfSiteTopic['references'])
+    data_type = FieldProperty(IWfSiteTopic['data_type'])
 
 register_content_type(WfSiteTopic)
 
--- a/src/pyams_content/shared/site/interfaces.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/site/interfaces.py	Tue Nov 19 16:39:10 2019 +0100
@@ -9,6 +9,8 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
+from pyams_content.shared.common.interfaces.types import DATA_TYPES_VOCABULARY
+
 
 __docformat__ = 'restructuredtext'
 
@@ -149,6 +151,11 @@
 class IWfSiteTopic(IWfTopic, IInternalReferencesList):
     """Site topic interface"""
 
+    data_type = Choice(title=_("Data type"),
+                       description=_("Type of content data"),
+                       required=False,
+                       vocabulary=DATA_TYPES_VOCABULARY)
+
 
 class IWfSiteTopicFactory(IWfTopicFactory):
     """Topic factory interface"""
--- a/src/pyams_content/shared/site/manager.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/site/manager.py	Tue Nov 19 16:39:10 2019 +0100
@@ -9,6 +9,8 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
+from pyams_content.shared.common.types import TypedSharedToolMixin
+
 
 __docformat__ = 'restructuredtext'
 
@@ -47,10 +49,11 @@
 from pyams_utils.vocabulary import vocabulary_config
 
 
-@implementer(ISiteManager, IParagraphFactorySettings, IThemesManagerTarget, ICollectionsManagerTarget,
-             IPictogramManagerTarget, IIllustrationTarget, ILinkIllustrationTarget, IPortalContext, IHeaderTarget,
-             IFooterTarget, IPreviewTarget)
-class SiteManager(SiteContainerMixin, OrderedContainer, BaseSharedTool, UserSkinnableContent):
+@implementer(ISiteManager, IParagraphFactorySettings, IThemesManagerTarget,
+             ICollectionsManagerTarget, IPictogramManagerTarget, IIllustrationTarget,
+             ILinkIllustrationTarget, IPortalContext, IHeaderTarget, IFooterTarget, IPreviewTarget)
+class SiteManager(SiteContainerMixin, OrderedContainer, BaseSharedTool, TypedSharedToolMixin,
+                  UserSkinnableContent):
     """Site manager persistent class"""
 
     description = FieldProperty(ISiteManager['description'])
@@ -133,6 +136,6 @@
 
     def __init__(self, context):
         request = query_request()
-        super(SiteManagerVocabulary, self).__init__([SimpleTerm(v, title=II18n(t).query_attribute('title',
-                                                                                                  request=request))
-                                                     for v, t in get_utilities_for(self.interface)])
+        super(SiteManagerVocabulary, self).__init__(
+            [SimpleTerm(v, title=II18n(t).query_attribute('title', request=request))
+             for v, t in get_utilities_for(self.interface)])
--- a/src/pyams_content/shared/site/zmi/__init__.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/site/zmi/__init__.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,9 +10,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
-
 from uuid import uuid4
 
 from pyramid.decorator import reify
@@ -23,10 +20,10 @@
 from zope.lifecycleevent import ObjectCreatedEvent
 from zope.schema import Int
 
-from pyams_content import _
 from pyams_content.interfaces import CREATE_CONTENT_PERMISSION
-from pyams_content.shared.common.interfaces import IWfSharedContent
-from pyams_content.shared.common.zmi import SharedContentAJAXAddForm, SharedContentAddForm
+from pyams_content.shared.common.zmi import SharedContentAJAXAddForm
+from pyams_content.shared.common.zmi.types import TypedSharedContentAddForm
+from pyams_content.shared.site import IWfSiteTopic
 from pyams_content.shared.site.interfaces import ISiteContainer, ISiteManager
 from pyams_content.shared.site.zmi.widget import SiteManagerFoldersSelectorFieldWidget
 from pyams_form.form import ajax_config
@@ -43,6 +40,11 @@
 from pyams_zmi.layer import IAdminLayer
 
 
+__docformat__ = 'restructuredtext'
+
+from pyams_content import _
+
+
 @viewlet_config(name='add-topic.menu', context=ISiteContainer, layer=IAdminLayer, view=Interface,
                 manager=IToolbarAddingMenu, permission=CREATE_CONTENT_PERMISSION, weight=20)
 class TopicAddMenu(ToolbarMenuItem):
@@ -54,7 +56,7 @@
     modal_target = True
 
 
-class ITopicAddFormFields(IWfSharedContent):
+class ITopicAddFormFields(IWfSiteTopic):
     """Topic add form fields interface"""
 
     parent = Int(title=_("Parent"),
@@ -68,12 +70,12 @@
                 permission=CREATE_CONTENT_PERMISSION)
 @ajax_config(name='add-topic.json', context=ISiteContainer, layer=IPyAMSLayer,
              base=SharedContentAJAXAddForm)
-class TopicAddForm(SharedContentAddForm):
+class TopicAddForm(TypedSharedContentAddForm):
     """Topic add form"""
 
     legend = _("Add topic")
 
-    fields = field.Fields(ITopicAddFormFields).select('title', 'parent', 'notepad')
+    fields = field.Fields(ITopicAddFormFields).select('title', 'data_type', 'parent', 'notepad')
     fields['parent'].widgetFactory = SiteManagerFoldersSelectorFieldWidget
 
     edit_permission = CREATE_CONTENT_PERMISSION
--- a/src/pyams_content/shared/site/zmi/container.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/site/zmi/container.py	Tue Nov 19 16:39:10 2019 +0100
@@ -51,7 +51,8 @@
 from pyams_skin.viewlet.menu import MenuItem
 from pyams_skin.viewlet.toolbar import ToolbarMenuItem
 from pyams_template.template import template_config
-from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, adapter_config
+from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, adapter_config, \
+    NullAdapter
 from pyams_utils.date import format_datetime
 from pyams_utils.fanstatic import get_resource_path
 from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
@@ -412,6 +413,11 @@
     }
 
 
+@adapter_config(name='type', context=(IBaseSiteItem, IPyAMSLayer, ISiteTreeTable), provides=IColumn)
+class SiteContainerTreeTypeColumn(NullAdapter):
+    """Site container tree type column -- disabled in site tree view!"""
+
+
 @adapter_config(name='name', context=(IBaseSiteItem, IPyAMSLayer, ISiteTreeTable), provides=IColumn)
 class SiteContainerTreeNameColumn(NameColumn):
     """Site container tree name column"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/site/zmi/summary.py	Tue Nov 19 16:39:10 2019 +0100
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2008-2019 Thierry Florac <tflorac AT ulthar.net>
+# 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.
+#
+
+from z3c.form import field
+
+from pyams_content.shared.common import IWfSharedContent
+from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm
+from pyams_content.shared.common.zmi.types.summary import TypedSharedContentDublinCoreSummary
+from pyams_content.shared.site import IWfSiteTopic
+from pyams_form.interfaces.form import IInnerTabForm
+from pyams_sequence.interfaces import ISequentialIdInfo
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.adapter import adapter_config
+
+
+__docformat__ = 'restructuredtext'
+
+
+@adapter_config(name='dublincore-summary',
+                context=(IWfSiteTopic, IPyAMSLayer, SharedContentSummaryForm),
+                provides=IInnerTabForm)
+class SiteTopicDublinCoreSummary(TypedSharedContentDublinCoreSummary):
+    """Site topic DublinCore summary"""
+
+    @property
+    def fields(self):
+        fields = field.Fields(IWfSharedContent).select('title') + \
+                 field.Fields(IWfSiteTopic).select('data_type') + \
+                 field.Fields(ISequentialIdInfo).select('public_oid')
+        return fields
--- a/src/pyams_content/shared/topic/__init__.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/topic/__init__.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,27 +10,29 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from zope.interface import implementer, provider
 from zope.schema.fieldproperty import FieldProperty
 
-from pyams_content.component.illustration.interfaces import IIllustrationTarget, ILinkIllustrationTarget
+from pyams_content.component.illustration.interfaces import IIllustrationTarget, \
+    ILinkIllustrationTarget
 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget
 from pyams_content.component.theme.interfaces import ITagsTarget, IThemesTarget
 from pyams_content.features.preview.interfaces import IPreviewTarget
 from pyams_content.features.review.interfaces import IReviewTarget
-from pyams_content.shared.common import SharedContent, register_content_type
+from pyams_content.shared.common import SharedContent, WfSharedContent, register_content_type
 from pyams_content.shared.common.interfaces import IWfSharedContentFactory
-from pyams_content.shared.common.types import WfTypedSharedContent
-from pyams_content.shared.topic.interfaces import ITopic, IWfTopic, IWfTopicFactory, TOPIC_CONTENT_NAME, \
-    TOPIC_CONTENT_TYPE
+from pyams_content.shared.common.types import WfTypedSharedContentMixin
+from pyams_content.shared.topic.interfaces import ITopic, IWfTopic, IWfTopicFactory, \
+    TOPIC_CONTENT_NAME, TOPIC_CONTENT_TYPE
 from pyams_utils.adapter import adapter_config
 
 
+__docformat__ = 'restructuredtext'
+
+
 @implementer(IWfTopic, IIllustrationTarget, ILinkIllustrationTarget, IParagraphContainerTarget,
              ITagsTarget, IThemesTarget, IPreviewTarget, IReviewTarget)
-class WfTopic(WfTypedSharedContent):
+class WfTopic(WfSharedContent, WfTypedSharedContentMixin):
     """Base topic"""
 
     content_type = TOPIC_CONTENT_TYPE
--- a/src/pyams_content/shared/topic/interfaces.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/topic/interfaces.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,16 +10,17 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from zope.interface import Interface
 from zope.schema import Choice
 
-from pyams_content.shared.common.interfaces import ISharedContent
-from pyams_content.shared.common.interfaces.types import ITypedSharedToolPortalContext, \
-    IWfTypedSharedContentPortalContext, DATA_TYPES_VOCABULARY
+from pyams_content.shared.common.interfaces import ISharedContent, ISharedToolPortalContext, \
+    IWfSharedContentPortalContext
+from pyams_content.shared.common.interfaces.types import DATA_TYPES_VOCABULARY
 from pyams_sequence.interfaces import IInternalReferencesList
 
+
+__docformat__ = 'restructuredtext'
+
 from pyams_content import _
 
 
@@ -27,7 +28,7 @@
 TOPIC_CONTENT_NAME = _("Topic")
 
 
-class ITopicManager(ITypedSharedToolPortalContext):
+class ITopicManager(ISharedToolPortalContext):
     """Topic manager interface"""
 
 
@@ -35,7 +36,7 @@
     """Topic manager factory interface"""
 
 
-class IWfTopic(IWfTypedSharedContentPortalContext, IInternalReferencesList):
+class IWfTopic(IWfSharedContentPortalContext, IInternalReferencesList):
     """Topic interface"""
 
     data_type = Choice(title=_("Data type"),
--- a/src/pyams_content/shared/topic/manager.py	Wed Nov 06 16:54:59 2019 +0100
+++ b/src/pyams_content/shared/topic/manager.py	Tue Nov 19 16:39:10 2019 +0100
@@ -10,8 +10,6 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from pyramid.events import subscriber
 from zope.component.interfaces import ISite
 from zope.interface import implementer
@@ -22,16 +20,21 @@
 from pyams_content.component.theme.interfaces import IThemesManagerTarget
 from pyams_content.reference.pictograms.interfaces import IPictogramManagerTarget
 from pyams_content.shared.common.interfaces import ISharedContentFactory
-from pyams_content.shared.common.types import TypedSharedTool
+from pyams_content.shared.common.manager import SharedTool
+from pyams_content.shared.common.types import TypedSharedToolMixin
 from pyams_content.shared.topic import Topic
-from pyams_content.shared.topic.interfaces import ITopicManager, ITopicManagerFactory, TOPIC_CONTENT_TYPE
+from pyams_content.shared.topic.interfaces import ITopicManager, ITopicManagerFactory, \
+    TOPIC_CONTENT_TYPE
 from pyams_utils.adapter import adapter_config
 from pyams_utils.registry import utility_config
 from pyams_utils.traversing import get_parent
 
 
+__docformat__ = 'restructuredtext'
+
+
 @implementer(ITopicManager, IParagraphFactorySettings, IThemesManagerTarget, IPictogramManagerTarget)
-class TopicManager(TypedSharedTool):
+class TopicManager(SharedTool, TypedSharedToolMixin):
     """Topic manager class"""
 
     shared_content_type = TOPIC_CONTENT_TYPE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/shared/topic/zmi/summary.py	Tue Nov 19 16:39:10 2019 +0100
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2008-2019 Thierry Florac <tflorac AT ulthar.net>
+# 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.
+#
+
+from z3c.form import field
+
+from pyams_content.shared.common import IWfSharedContent
+from pyams_content.shared.common.zmi.summary import SharedContentSummaryForm
+from pyams_content.shared.common.zmi.types.summary import TypedSharedContentDublinCoreSummary
+from pyams_content.shared.topic import IWfTopic
+from pyams_form.interfaces.form import IInnerTabForm
+from pyams_sequence.interfaces import ISequentialIdInfo
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.adapter import adapter_config
+
+
+__docformat__ = 'restructuredtext'
+
+
+@adapter_config(name='dublincore-summary',
+                context=(IWfTopic, IPyAMSLayer, SharedContentSummaryForm),
+                provides=IInnerTabForm)
+class TopicDublinCoreSummary(TypedSharedContentDublinCoreSummary):
+    """Topic DublinCore summary"""
+
+    @property
+    def fields(self):
+        fields = field.Fields(IWfSharedContent).select('title') + \
+                 field.Fields(IWfTopic).select('data_type') + \
+                 field.Fields(ISequentialIdInfo).select('public_oid')
+        return fields