src/pyams_skin/configuration.py
changeset 85 0dd5876f9d70
parent 79 ed37e7df3d47
child 115 2de951190b08
--- a/src/pyams_skin/configuration.py	Wed Oct 07 17:52:40 2015 +0200
+++ b/src/pyams_skin/configuration.py	Wed Oct 07 17:53:40 2015 +0200
@@ -18,8 +18,9 @@
 
 # import interfaces
 from pyams_skin.interfaces.configuration import IStaticConfiguration, IConfiguration, \
-    SKIN_CONFIGURATION_KEY
-from pyams_utils.interfaces.site import IStaticConfigurationManager, IConfigurationManager, IConfigurationFactory
+    SKIN_CONFIGURATION_KEY, IBackOfficeConfiguration, SKIN_BACK_CONFIGURATION_KEY
+from pyams_utils.interfaces.site import IStaticConfigurationManager, IConfigurationManager, IConfigurationFactory, \
+    IBackOfficeConfigurationFactory
 from pyams_utils.interfaces.tales import ITALESExtension
 from zope.annotation.interfaces import IAnnotations
 from zope.traversing.interfaces import ITraversable
@@ -41,6 +42,10 @@
 from pyams_skin import _
 
 
+#
+# Static configuration
+#
+
 @adapter_config(context=(IStaticConfigurationManager, Interface, Interface), provides=IStaticConfiguration)
 class StaticConfiguration(object):
     """Default static configuration"""
@@ -89,6 +94,11 @@
         return registry.queryMultiAdapter((target, self.request, self.view), IStaticConfiguration)
 
 
+#
+# Dynamic front-office configuration
+# May be overriden by custom applications
+#
+
 @implementer(IConfiguration)
 class Configuration(Persistent, Contained):
     """Manageable configuration"""
@@ -107,10 +117,9 @@
     configuration = annotations.get(SKIN_CONFIGURATION_KEY)
     if configuration is None:
         registry = check_request().registry
-        factory = registry.queryAdapter(context, IConfigurationFactory)
-        if factory is not None:
-            configuration = annotations[SKIN_CONFIGURATION_KEY] = factory()
-            locate(configuration, context, '++configuration++')
+        factory = registry.queryAdapter(context, IConfigurationFactory, default=Configuration)
+        configuration = annotations[SKIN_CONFIGURATION_KEY] = factory()
+        locate(configuration, context, '++configuration++')
     return configuration
 
 
@@ -142,3 +151,63 @@
         request.context = configuration.icon
         return MediaFileView(request)
     return HTTPNotFound()
+
+
+#
+# Dynamic back-office configuration
+# May be overriden by custom applications
+#
+
+@implementer(IBackOfficeConfiguration)
+class BackOfficeConfiguration(Persistent, Contained):
+    """Back-office manageable configuration"""
+
+    title = FieldProperty(IBackOfficeConfiguration['title'])
+    login_header = FieldProperty(IBackOfficeConfiguration['login_header'])
+    login_footer = FieldProperty(IBackOfficeConfiguration['login_footer'])
+    icon = FileProperty(IBackOfficeConfiguration['icon'])
+    logo = FileProperty(IBackOfficeConfiguration['logo'])
+    display_content_icon = FieldProperty(IBackOfficeConfiguration['display_content_icon'])
+
+
+@adapter_config(context=IConfigurationManager, provides=IBackOfficeConfiguration)
+def BackOfficeConfigurationFactory(context):
+    """Back-office configuration factory"""
+    annotations = IAnnotations(context)
+    configuration = annotations.get(SKIN_BACK_CONFIGURATION_KEY)
+    if configuration is None:
+        registry = check_request().registry
+        factory = registry.queryAdapter(context, IBackOfficeConfigurationFactory, default=BackOfficeConfiguration)
+        configuration = annotations[SKIN_BACK_CONFIGURATION_KEY] = factory()
+        locate(configuration, context, '++back-configuration++')
+    return configuration
+
+
+@adapter_config(name='back_configuration', context=(Interface, Interface, Interface), provides=ITALESExtension)
+class BackOfficeConfigurationTalesExtension(ContextRequestViewAdapter):
+    """extension:back_configuration TALES expression"""
+
+    def render(self, context=None):
+        if context is None:
+            context = self.context
+        manager = get_parent(context, IConfigurationManager)
+        if manager is not None:
+            return IBackOfficeConfiguration(manager)
+
+
+@adapter_config(name='back-configuration', context=IConfigurationManager, provides=ITraversable)
+class BackOfficeConfigurationTraverser(ContextAdapter):
+    """++back-configuration++ namespace traverser"""
+
+    def traverse(self, name, furtherpath=None):
+        return IBackOfficeConfiguration(self.context)
+
+
+@view_config(name='back-favicon.ico', context=IConfigurationManager)
+def back_office_site_icon(request):
+    configuration = IBackOfficeConfiguration(request.context)
+    if configuration.icon is not None:
+        request = request.copy()
+        request.context = configuration.icon
+        return MediaFileView(request)
+    return HTTPNotFound()