Added container class to skin configuration
authorThierry Florac <tflorac@ulthar.net>
Tue, 13 Jul 2021 08:00:55 +0200
changeset 575 d9128c1432af
parent 574 ecc2ce6a7172
child 576 998a3b7cac64
Added container class to skin configuration
src/pyams_skin/interfaces/__init__.py
src/pyams_skin/skin.py
--- a/src/pyams_skin/interfaces/__init__.py	Thu May 27 14:15:54 2021 +0200
+++ b/src/pyams_skin/interfaces/__init__.py	Tue Jul 13 08:00:55 2021 +0200
@@ -78,6 +78,10 @@
     def get_skin(self, request=None):
         """Get skin matching this content"""
 
+    container_class = TextLine(title=_("Container class"),
+                               description=_("Main page container class"),
+                               required=False)
+
     custom_stylesheet = FileField(title=_("Custom stylesheet"),
                                   description=_("This custom stylesheet will be used to override selected theme styles"),
                                   required=False)
--- a/src/pyams_skin/skin.py	Thu May 27 14:15:54 2021 +0200
+++ b/src/pyams_skin/skin.py	Tue Jul 13 08:00:55 2021 +0200
@@ -10,30 +10,35 @@
 # FOR A PARTICULAR PURPOSE.
 #
 
-__docformat__ = 'restructuredtext'
-
 import logging
-logger = logging.getLogger('PyAMS (skin)')
 
 from pyramid.events import subscriber
 from pyramid.threadlocal import get_current_request
 from pyramid_zope_request import PyramidPublisherRequest
-from zope.interface import implementer, directlyProvidedBy, directlyProvides
+from zope.interface import Interface, directlyProvidedBy, directlyProvides, implementer
 from zope.schema.fieldproperty import FieldProperty
 from zope.traversing.interfaces import IBeforeTraverseEvent
 
-from pyams_file.interfaces import DELETED_FILE
+from pyams_file.interfaces import DELETED_FILE, IFileInfo
 from pyams_file.property import FileProperty
 from pyams_skin.interfaces import ISkin, ISkinnable, IUserSkinnable, SkinChangedEvent
 from pyams_skin.layer import IBaseLayer, IPyAMSLayer
+from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
 from pyams_utils.interfaces.site import ISiteRoot
+from pyams_utils.interfaces.tales import ITALESExtension
 from pyams_utils.registry import utility_config
 from pyams_utils.traversing import get_parent
 from pyams_utils.zodb import volatile_property
 
+
+__docformat__ = 'restructuredtext'
+
 from pyams_skin import _
 
 
+logger = logging.getLogger('PyAMS (skin)')
+
+
 @implementer(ISkinnable)
 class SkinnableContent(object):
     """Skinnable content base class"""
@@ -41,6 +46,7 @@
     _inherit_skin = FieldProperty(ISkinnable['inherit_skin'])
     _skin = FieldProperty(IUserSkinnable['skin'])
 
+    _container_class = FieldProperty(ISkinnable['container_class'])
     _custom_stylesheet = FileProperty(ISkinnable['custom_stylesheet'])
     _editor_stylesheet = FileProperty(ISkinnable['editor_stylesheet'])
     _custom_script = FileProperty(ISkinnable['custom_script'])
@@ -89,6 +95,18 @@
         del self.skin_parent
 
     @property
+    def container_class(self):
+        if not self.inherit_skin:
+            return self._container_class
+        else:
+            return self.skin_parent.container_class
+
+    @container_class.setter
+    def container_class(self, value):
+        if not self.inherit_skin:
+            self._container_class = value
+
+    @property
     def custom_stylesheet(self):
         if not self.inherit_skin:
             return self._custom_stylesheet
@@ -101,6 +119,7 @@
             self._custom_stylesheet = value
             if value and (value is not DELETED_FILE):
                 self._custom_stylesheet.content_type = 'text/css'
+                IFileInfo(self._custom_stylesheet).filename = 'skin.css'
 
     @property
     def editor_stylesheet(self):
@@ -115,6 +134,7 @@
             self._editor_stylesheet = value
             if value and (value is not DELETED_FILE):
                 self._editor_stylesheet.content_type = 'text/css'
+                IFileInfo(self._editor_stylesheet).filename = 'editor-skin.css'
 
     @property
     def custom_script(self):
@@ -129,6 +149,7 @@
             self._custom_script = value
             if value and (value is not DELETED_FILE):
                 self._custom_script.content_type = 'text/javascript'
+                IFileInfo(self._custom_stylesheet).filename = 'skin.js'
 
     def get_skin(self, request=None):
         parent = self.skin_parent
@@ -142,6 +163,22 @@
                 return request.registry.queryUtility(ISkin, skin)
 
 
+@adapter_config(name='container_class',
+                context=(Interface, IPyAMSLayer, Interface),
+                provides=ITALESExtension)
+class ContainerClassTALESExtension(ContextRequestViewAdapter):
+    """Container class TALES extension"""
+
+    def render(self, context=None, default=''):
+        if context is None:
+            context = self.context
+        result = default
+        skin = get_parent(context, ISkinnable)
+        if skin is not None:
+            result = skin.container_class or result
+        return result
+
+
 @implementer(IUserSkinnable)
 class UserSkinnableContent(SkinnableContent):
     """User skinnable content base class"""