diff -r 000000000000 -r bca7a7e058a3 src/pyams_skin/configuration.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_skin/configuration.py Thu Feb 13 11:43:31 2020 +0100 @@ -0,0 +1,156 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# 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' + +from persistent import Persistent +from pyramid.httpexceptions import HTTPNotFound +from pyramid.view import view_config +from zope.container.contained import Contained +from zope.interface import Interface, implementer +from zope.schema.fieldproperty import FieldProperty +from zope.traversing.interfaces import ITraversable + +from pyams_file.property import FileProperty +from pyams_file.views.file import FileView +from pyams_skin.interfaces import IContextTitlePrefix +from pyams_skin.interfaces.configuration import IBackOfficeConfiguration, IConfiguration, SKIN_BACK_CONFIGURATION_KEY, \ + SKIN_CONFIGURATION_KEY +from pyams_utils.adapter import ContextAdapter, ContextRequestViewAdapter, adapter_config, get_annotation_adapter +from pyams_utils.factory import factory_config +from pyams_utils.interfaces.site import IConfigurationManager +from pyams_utils.interfaces.tales import ITALESExtension +from pyams_utils.registry import get_global_registry +from pyams_utils.traversing import get_parent + + +# +# Dynamic front-office configuration +# May be overriden by custom applications +# + +@factory_config(IConfiguration) +class Configuration(Persistent, Contained): + """Manageable configuration""" + + title = FieldProperty(IConfiguration['title']) + short_title = FieldProperty(IConfiguration['short_title']) + description = FieldProperty(IConfiguration['description']) + author = FieldProperty(IConfiguration['author']) + icon = FileProperty(IConfiguration['icon']) + logo = FileProperty(IConfiguration['logo']) + + @staticmethod + def get_title_prefix(request): + adapter = get_global_registry().queryMultiAdapter((request.context, request), IContextTitlePrefix) + if adapter is not None: + return adapter.prefix + + +@adapter_config(context=IConfigurationManager, provides=IConfiguration) +def configuration_factory(context): + """Configuration factory""" + return get_annotation_adapter(context, SKIN_CONFIGURATION_KEY, IConfiguration, + name='++configuration++') + + +@adapter_config(name='configuration', context=(Interface, Interface, Interface), provides=ITALESExtension) +class ConfigurationTalesExtension(ContextRequestViewAdapter): + """extension: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 IConfiguration(manager) + + +@adapter_config(name='configuration', context=IConfigurationManager, provides=ITraversable) +class ConfigurationTraverser(ContextAdapter): + """++configuration++ namespace traverser""" + + def traverse(self, name, furtherpath=None): + return IConfiguration(self.context) + + +@view_config(name='favicon.ico', context=IConfigurationManager) +def site_icon(request): + configuration = IConfiguration(request.context) + if configuration.icon is not None: + request = request.copy() + request.context = configuration.icon + return FileView(request) + return HTTPNotFound() + + +# +# Dynamic back-office configuration +# May be overriden by custom applications +# + +@factory_config(IBackOfficeConfiguration) +class BackOfficeConfiguration(Persistent, Contained): + """Back-office manageable configuration""" + + title = FieldProperty(IBackOfficeConfiguration['title']) + short_title = FieldProperty(IBackOfficeConfiguration['short_title']) + login_header = FieldProperty(IBackOfficeConfiguration['login_header']) + login_footer = FieldProperty(IBackOfficeConfiguration['login_footer']) + icon = FileProperty(IBackOfficeConfiguration['icon']) + logo = FileProperty(IBackOfficeConfiguration['logo']) + login_logo = FileProperty(IBackOfficeConfiguration['login_logo']) + display_content_icon = FieldProperty(IBackOfficeConfiguration['display_content_icon']) + display_shared_tool_title = FieldProperty(IBackOfficeConfiguration['display_shared_tool_title']) + + @staticmethod + def get_title_prefix(request): + adapter = request.registry.queryMultiAdapter((request.context, request), IContextTitlePrefix) + if adapter is not None: + return adapter.prefix + + +@adapter_config(context=IConfigurationManager, provides=IBackOfficeConfiguration) +def back_office_configuration_factory(context): + """Back-office configuration factory""" + return get_annotation_adapter(context, SKIN_BACK_CONFIGURATION_KEY, IBackOfficeConfiguration, + name='++back-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 FileView(request) + return HTTPNotFound()