Allow inheritance of themes
authorThierry Florac <tflorac@ulthar.net>
Fri, 13 Nov 2020 13:01:02 +0100
changeset 1423 31c1bc24a308
parent 1422 d3713e98bba0
child 1424 60d14cecb200
Allow inheritance of themes
src/pyams_content/component/theme/__init__.py
src/pyams_content/component/theme/interfaces.py
src/pyams_content/component/theme/zmi/__init__.py
src/pyams_content/component/theme/zmi/manager.py
--- a/src/pyams_content/component/theme/__init__.py	Tue Sep 08 12:23:21 2020 +0200
+++ b/src/pyams_content/component/theme/__init__.py	Fri Nov 13 13:01:02 2020 +0100
@@ -11,7 +11,10 @@
 #
 
 from persistent import Persistent
+from pyramid.events import subscriber
 from zope.container.contained import Contained
+from zope.interface import alsoProvides
+from zope.lifecycleevent import IObjectAddedEvent
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_content.component.theme.interfaces import COLLECTIONS_INFO_KEY, \
@@ -21,8 +24,10 @@
     THEMES_INFO_KEY, THEMES_MANAGER_KEY
 from pyams_content.features.checker import BaseContentChecker
 from pyams_content.features.checker.interfaces import ERROR_VALUE, IContentChecker
+from pyams_content.shared.site.interfaces import ISiteFolder
 from pyams_utils.adapter import adapter_config, get_annotation_adapter
 from pyams_utils.factory import factory_config
+from pyams_utils.inherit import BaseInheritInfo, InheritedFieldProperty
 
 
 __docformat__ = 'restructuredtext'
@@ -104,10 +109,14 @@
 
 
 @factory_config(IThemesInfo)
-class ThemesInfo(Persistent, Contained):
+class ThemesInfo(BaseInheritInfo, Persistent, Contained):
     """Themes info persistent class"""
 
-    themes = FieldProperty(IThemesInfo['themes'])
+    adapted_interface = IThemesInfo
+    target_interface = IThemesTarget
+
+    _themes = FieldProperty(IThemesInfo['themes'])
+    themes = InheritedFieldProperty(IThemesInfo['themes'])
 
 
 @adapter_config(context=IThemesTarget, provides=IThemesInfo)
@@ -135,6 +144,12 @@
         return output
 
 
+@subscriber(IObjectAddedEvent, context_selector=ISiteFolder, parent_selector=IThemesTarget)
+def handle_added_site_folder(event):
+    """Handle site folder when added to a themes target"""
+    alsoProvides(event.object, IThemesTarget)
+
+
 #
 # Collections management
 #
--- a/src/pyams_content/component/theme/interfaces.py	Tue Sep 08 12:23:21 2020 +0200
+++ b/src/pyams_content/component/theme/interfaces.py	Fri Nov 13 13:01:02 2020 +0100
@@ -10,15 +10,18 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 from zope.interface import Interface, Invalid, invariant
 from zope.schema import Bool, Choice
 
-from pyams_content import _
 from pyams_thesaurus.interfaces.thesaurus import IThesaurusContextManager, \
     IThesaurusContextManagerTarget
 from pyams_thesaurus.schema import ThesaurusTermsListField
+from pyams_utils.interfaces.inherit import IInheritInfo
+
+
+__docformat__ = 'restructuredtext'
+
+from pyams_content import _
 
 
 #
@@ -92,7 +95,7 @@
     """Marker interface for tools managing themes"""
 
 
-class IThemesInfo(Interface):
+class IThemesInfo(IInheritInfo):
     """Themes information interface"""
 
     themes = ThesaurusTermsListField(title=_("Themes"),
--- a/src/pyams_content/component/theme/zmi/__init__.py	Tue Sep 08 12:23:21 2020 +0200
+++ b/src/pyams_content/component/theme/zmi/__init__.py	Fri Nov 13 13:01:02 2020 +0100
@@ -11,14 +11,16 @@
 #
 
 from z3c.form import field
+from z3c.form.browser.checkbox import SingleCheckBoxFieldWidget
 from zope.interface import implementer
 
 from pyams_content.component.theme import ICollectionsInfo, ICollectionsManager, \
-    ICollectionsManagerTarget, ICollectionsTarget, ITagsInfo, ITagsManager, ITagsTarget, \
+    ICollectionsTarget, ITagsInfo, ITagsManager, ITagsTarget, \
     IThemesInfo, IThemesManager, IThemesManagerTarget, IThemesTarget
 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
 from pyams_content.shared.common.zmi import WfSharedContentHeaderAdapter
 from pyams_form.form import AJAXEditForm, EditForm, ajax_config
+from pyams_form.group import NamedWidgetsGroup
 from pyams_form.interfaces.form import IWidgetForm
 from pyams_pagelet.pagelet import pagelet_config
 from pyams_skin.interfaces import IDialog, IInnerPage, IPageHeader
@@ -90,7 +92,7 @@
 #
 
 @viewlet_config(name='themes.menu', context=IThemesTarget, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=352)
+                manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=360)
 class ThemesMenu(MenuItem):
     """Themes menu"""
 
@@ -107,11 +109,33 @@
     label_css_class = 'control-label hidden'
     input_css_class = 'col-md-12'
 
-    fields = field.Fields(IThemesInfo)
-    fields['themes'].widgetFactory = ThesaurusTermsTreeFieldWidget
+    @property
+    def fields(self):
+        if IThemesInfo(self.context).can_inherit:
+            fields = field.Fields(IThemesInfo).select('no_inherit', 'themes')
+            fields['no_inherit'].widgetFactory = SingleCheckBoxFieldWidget
+        else:
+            fields = field.Fields(IThemesInfo).select('themes')
+        fields['themes'].widgetFactory = ThesaurusTermsTreeFieldWidget
+        return fields
 
     edit_permission = MANAGE_CONTENT_PERMISSION
 
+    def updateGroups(self):
+        if IThemesInfo(self.context).can_inherit:
+            group = NamedWidgetsGroup(self, 'themes', self.widgets,
+                                      ('no_inherit', 'themes'),
+                                      legend=_("Don't inherit parent themes"),
+                                      css_class='inner',
+                                      switch=True,
+                                      checkbox_switch=True,
+                                      checkbox_mode='disable',
+                                      checkbox_field=IThemesInfo['no_inherit'])
+        else:
+            group = NamedWidgetsGroup(self, 'themes', self.widgets, (), css_class='inner')
+        self.add_group(group)
+        super(BaseThemesEditForm, self).updateGroups()
+
     def updateWidgets(self, prefix=None):
         super(BaseThemesEditForm, self).updateWidgets(prefix)
         if 'themes' in self.widgets:
@@ -129,15 +153,19 @@
     icon_class = 'fa fa-fw fa-tags'
 
 
-@pagelet_config(name='themes.html', context=IThemesTarget, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
-@ajax_config(name='themes.json', context=IThemesTarget, layer=IPyAMSLayer, base=AJAXEditForm)
+@pagelet_config(name='themes.html', context=IThemesTarget, layer=IPyAMSLayer,
+                permission=VIEW_SYSTEM_PERMISSION)
+@ajax_config(name='themes.json', context=IThemesTarget, layer=IPyAMSLayer,
+             base=AJAXEditForm)
 @implementer(IWidgetForm, IInnerPage)
 class ThemesEditForm(BaseThemesEditForm, AdminEditForm):
     """Themes edit form"""
 
 
-@pagelet_config(name='themes-dialog.html', context=IThemesTarget, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
-@ajax_config(name='themes-dialog.json', context=IThemesTarget, layer=IPyAMSLayer, base=AJAXEditForm)
+@pagelet_config(name='themes-dialog.html', context=IThemesTarget, layer=IPyAMSLayer,
+                permission=VIEW_SYSTEM_PERMISSION)
+@ajax_config(name='themes-dialog.json', context=IThemesTarget, layer=IPyAMSLayer,
+             base=AJAXEditForm)
 @implementer(IDialog)
 class DialogThemesEditForm(BaseThemesEditForm, AdminDialogEditForm):
     """Dialog themes edit form"""
@@ -150,7 +178,7 @@
 #
 
 @viewlet_config(name='collections.menu', context=ICollectionsTarget, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=354)
+                manager=IPropertiesMenu, permission=VIEW_SYSTEM_PERMISSION, weight=370)
 class CollectionsMenu(MenuItem):
     """Collections menu"""
 
--- a/src/pyams_content/component/theme/zmi/manager.py	Tue Sep 08 12:23:21 2020 +0200
+++ b/src/pyams_content/component/theme/zmi/manager.py	Fri Nov 13 13:01:02 2020 +0100
@@ -40,17 +40,17 @@
 #
 
 @viewlet_config(name='tags-manager.menu', context=ITagsManagerTarget, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=40)
+                manager=IPropertiesMenu, permission=MANAGE_SITE_ROOT_PERMISSION, weight=730)
 class TagsManagerMenu(MenuItem):
     """Tags menu"""
 
     label = _("Tags settings...")
     icon_class = 'fa-tag'
-    url = 'tags.html'
+    url = 'tags-manager.html'
     modal_target = True
 
 
-@pagelet_config(name='tags.html', context=ITagsManagerTarget, layer=IPyAMSLayer,
+@pagelet_config(name='tags-manager.html', context=ITagsManagerTarget, layer=IPyAMSLayer,
                 permission=MANAGE_SITE_ROOT_PERMISSION)
 @ajax_config(name='tags.json', context=ITagsManagerTarget, layer=IPyAMSLayer)
 class TagsManagerEditForm(AdminDialogEditForm):
@@ -104,17 +104,17 @@
 #
 
 @viewlet_config(name='themes-manager.menu', context=IThemesManagerTarget, layer=IAdminLayer,
-                manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION, weight=41)
+                manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION, weight=740)
 class ThemesManagerMenu(MenuItem):
     """Themes menu"""
 
     label = _("Themes settings...")
     icon_class = 'fa-tags'
-    url = 'themes.html'
+    url = 'themes-manager.html'
     modal_target = True
 
 
-@pagelet_config(name='themes.html', context=IThemesManagerTarget, layer=IPyAMSLayer,
+@pagelet_config(name='themes-manager.html', context=IThemesManagerTarget, layer=IPyAMSLayer,
                 permission=MANAGE_TOOL_PERMISSION)
 @ajax_config(name='themes.json', context=IThemesManagerTarget, layer=IPyAMSLayer)
 class ThemesManagerEditForm(AdminDialogEditForm):
@@ -156,17 +156,17 @@
 
 @viewlet_config(name='collections-manager.menu', context=ICollectionsManagerTarget,
                 layer=IAdminLayer, manager=IPropertiesMenu, permission=MANAGE_TOOL_PERMISSION,
-                weight=42)
+                weight=750)
 class CollectionsManagerMenu(MenuItem):
     """Collections menu"""
 
     label = _("Collections settings...")
     icon_class = 'fa-book'
-    url = 'collections.html'
+    url = 'collections-manager.html'
     modal_target = True
 
 
-@pagelet_config(name='collections.html', context=ICollectionsManagerTarget, layer=IPyAMSLayer,
+@pagelet_config(name='collections-manager.html', context=ICollectionsManagerTarget, layer=IPyAMSLayer,
                 permission=MANAGE_SITE_ROOT_PERMISSION)
 @ajax_config(name='collections.json', context=ICollectionsManagerTarget, layer=IPyAMSLayer)
 class CollectionsManagerEditForm(AdminDialogEditForm):