--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/configuration.py Sun Mar 11 11:15:28 2018 +0100
@@ -0,0 +1,112 @@
+#
+# Copyright (c) 2008-2018 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.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+import pkg_resources
+
+# import interfaces
+from pyams_utils.interfaces.site import ISiteRoot
+from pyams_utils.interfaces.tales import ITALESExtension
+from pyams_zmi.interfaces import IZMIConfiguration
+from pyams_zmi.layer import IAdminLayer
+from zope.annotation.interfaces import IAnnotations
+
+# import packages
+from persistent import Persistent
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_utils.traversing import get_parent
+from zope.container.contained import Contained
+from zope.interface import implementer, Interface
+from zope.location import locate
+from zope.schema.fieldproperty import FieldProperty
+
+
+@implementer(IZMIConfiguration)
+class ZMIConfiguration(Persistent, Contained):
+ """ZMI configuration class"""
+
+ application_package = FieldProperty(IZMIConfiguration['application_package'])
+ application_name = FieldProperty(IZMIConfiguration['application_name'])
+ inner_package = FieldProperty(IZMIConfiguration['inner_package'])
+ inner_package_name = FieldProperty(IZMIConfiguration['inner_package_name'])
+ version_location = FieldProperty(IZMIConfiguration['version_location'])
+
+ include_header = FieldProperty(IZMIConfiguration['include_header'])
+ fixed_header = FieldProperty(IZMIConfiguration['fixed_header'])
+ include_top_links = FieldProperty(IZMIConfiguration['include_top_links'])
+
+ include_site_search = FieldProperty(IZMIConfiguration['include_site_search'])
+ site_search_placeholder = FieldProperty(IZMIConfiguration['site_search_placeholder'])
+ site_search_handler = FieldProperty(IZMIConfiguration['site_search_handler'])
+ include_mobile_search = FieldProperty(IZMIConfiguration['include_mobile_search'])
+ mobile_search_placeholder = FieldProperty(IZMIConfiguration['mobile_search_placeholder'])
+ mobile_search_handler = FieldProperty(IZMIConfiguration['mobile_search_handler'])
+
+ include_user_activity = FieldProperty(IZMIConfiguration['include_user_activity'])
+ include_user_shortcuts = FieldProperty(IZMIConfiguration['include_user_shortcuts'])
+ include_logout_button = FieldProperty(IZMIConfiguration['include_logout_button'])
+ include_minify_button = FieldProperty(IZMIConfiguration['include_minify_button'])
+ include_flags = FieldProperty(IZMIConfiguration['include_flags'])
+
+ include_menus = FieldProperty(IZMIConfiguration['include_menus'])
+ fixed_navigation = FieldProperty(IZMIConfiguration['fixed_navigation'])
+ accordion_menus = FieldProperty(IZMIConfiguration['accordion_menus'])
+
+ include_ribbon = FieldProperty(IZMIConfiguration['include_ribbon'])
+ fixed_ribbon = FieldProperty(IZMIConfiguration['fixed_ribbon'])
+ include_reload_button = FieldProperty(IZMIConfiguration['include_reload_button'])
+
+ base_body_css_class = FieldProperty(IZMIConfiguration['base_body_css_class'])
+
+ @property
+ def version(self):
+ result = pkg_resources.get_distribution(self.application_package).version
+ if self.inner_package and (self.inner_package != self.application_package):
+ result += ' (%s v%s)' % (self.inner_package_name,
+ pkg_resources.get_distribution(self.inner_package).version)
+ return result
+
+ @property
+ def body_css_class(self):
+ result = self.base_body_css_class or ''
+ for attr in ('header', 'ribbon', 'navigation'):
+ if getattr(self, 'fixed_' + attr, False):
+ result += ' fixed-' + attr
+ return result
+
+
+ZMI_CONFIGURATION_KEY = 'pyams_zmi.configuration'
+
+
+@adapter_config(context=ISiteRoot, provides=IZMIConfiguration)
+def ZMIConfigurationFactory(context):
+ """ZMI configuration factory"""
+ annotations = IAnnotations(context)
+ configuration = annotations.get(ZMI_CONFIGURATION_KEY)
+ if configuration is None:
+ configuration = annotations[ZMI_CONFIGURATION_KEY] = ZMIConfiguration()
+ locate(configuration, context)
+ return configuration
+
+
+@adapter_config(name='zmi_configuration', context=(Interface, IAdminLayer, Interface), provides=ITALESExtension)
+class ZMIConfigurationTalesExtension(ContextRequestViewAdapter):
+ """extension:zmi_configuration TALES expression"""
+
+ def render(self, context=None):
+ if context is None:
+ context = self.context
+ target = get_parent(context, ISiteRoot)
+ return IZMIConfiguration(target)
--- a/src/pyams_zmi/interfaces/__init__.py Sun Mar 11 11:14:30 2018 +0100
+++ b/src/pyams_zmi/interfaces/__init__.py Sun Mar 11 11:15:28 2018 +0100
@@ -20,8 +20,12 @@
from pyramid.interfaces import IView
# import packages
+from pyams_i18n.schema import I18nTextLineField
from pyams_template.template import layout_config
-from zope.interface import Interface
+from zope.interface import Interface, Attribute
+from zope.schema import TextLine, Choice, Bool
+
+from pyams_zmi import _
@layout_config(template='templates/admin-layout.pt', layer=IAdminLayer)
@@ -31,3 +35,122 @@
class IPropertiesEditForm(Interface):
"""Properties edit form marker interface"""
+
+
+class IZMIConfiguration(Interface):
+ """Static configuration interface
+
+ These configuration options are used by default presentation layout
+ """
+
+ application_package = TextLine(title=_("Main package"),
+ description=_("This package is used to get current application version"),
+ default='pyams_skin',
+ required=False)
+
+ application_name = TextLine(title=_("Application name"),
+ description=_("This name is used to display application version"),
+ default='PyAMS',
+ required=False)
+
+ inner_package = TextLine(title=_("Inner package"),
+ description=_("This is another important package displayed in application version"),
+ default='pyams_skin',
+ required=False)
+
+ inner_package_name = TextLine(title=_("Inner package name"),
+ description=_("Package name used to display application version"),
+ required=False)
+
+ version = Attribute("Application version")
+
+ version_location = Choice(title=_("Version location"),
+ description=_("Position of version label"),
+ required=False,
+ values=(u'menus', u'shortcuts'),
+ default=u'menus')
+
+ include_header = Bool(title=_("Include header?"),
+ required=True,
+ default=True)
+
+ fixed_header = Bool(title=_("Fixed header?"),
+ required=True,
+ default=True)
+
+ include_top_links = Bool(title=_("Include top links?"),
+ required=True,
+ default=True)
+
+ include_site_search = Bool(title=_("Include site search?"),
+ required=False,
+ default=True)
+
+ site_search_placeholder = I18nTextLineField(title=_("Site search placeholder"),
+ required=False,
+ default=_("Search..."))
+
+ site_search_handler = TextLine(title=_("Site search handler"),
+ required=False,
+ default="#search.html")
+
+ include_mobile_search = Bool(title=_("Include mobile search?"),
+ required=False,
+ default=True)
+
+ mobile_search_placeholder = I18nTextLineField(title=_("Mobile search placeholder"),
+ required=False,
+ default=_("Search..."))
+
+ mobile_search_handler = TextLine(title=_("Mobile search handler"),
+ required=False,
+ default='#search.html')
+
+ include_user_activity = Bool(title=_("Include user dropdown window?"),
+ required=True,
+ default=True)
+
+ include_user_shortcuts = Bool(title=_("Include user shortcuts?"),
+ required=True,
+ default=True)
+
+ include_logout_button = Bool(title=_("Include logout button?"),
+ required=True,
+ default=True)
+
+ include_minify_button = Bool(title=_("Include minify button?"),
+ required=True,
+ default=True)
+
+ include_flags = Bool(title=_("Include flags menu?"),
+ required=True,
+ default=False)
+
+ include_menus = Bool(title=_("Include main menus?"),
+ required=True,
+ default=True)
+
+ fixed_navigation = Bool(title=_("Fixed menus?"),
+ required=True,
+ default=True)
+
+ accordion_menus = Bool(title=_("Display menus as accordion?"),
+ required=True,
+ default=True)
+
+ include_ribbon = Bool(title=_("Include ribbon?"),
+ required=True,
+ default=True)
+
+ fixed_ribbon = Bool(title=_("Fixed ribbon?"),
+ required=True,
+ default=True)
+
+ include_reload_button = Bool(title=_("Include reload button?"),
+ required=True,
+ default=False)
+
+ base_body_css_class = TextLine(title=_("Base body CSS class"),
+ required=False)
+
+ body_css_class = Attribute("HTML body CSS class")
\ No newline at end of file