--- a/src/pyams_zmi/admin.py Sun Mar 11 11:16:23 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2008-2015 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 interfaces
-from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
-from pyams_zmi.layer import IAdminLayer
-
-# import packages
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_template.template import template_config
-from pyams_zmi.view import AdminView
-from zope.interface import Interface
-
-
-@pagelet_config(name='admin', context=Interface, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
-@template_config(template='templates/admin-index.pt', layer=IAdminLayer)
-class MainAdminPage(AdminView):
- """Main administration page"""
--- a/src/pyams_zmi/control_panel.py Sun Mar 11 11:16:23 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-#
-# Copyright (c) 2008-2015 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
-from html import escape
-
-# import interfaces
-from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentHelp
-from pyams_skin.interfaces.container import ITableWithActions
-from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
-from pyams_utils.interfaces.site import IOptionalUtility
-from pyams_zmi.interfaces.menu import IControlPanelMenu, IUtilitiesMenu
-from pyams_zmi.layer import IAdminLayer
-from z3c.table.interfaces import IValues, IColumn
-from zope.component.interfaces import ISite
-
-# import packages
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.container import ContainerView
-from pyams_skin.help import ContentHelp
-from pyams_skin.page import DefaultPageHeaderAdapter
-from pyams_skin.table import BaseTable, TrashColumn
-from pyams_skin.viewlet.menu import MenuItem
-from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
-from pyams_utils.registry import registered_utilities
-from pyams_utils.text import text_to_html
-from pyams_utils.url import absolute_url
-from pyams_viewlet.manager import viewletmanager_config
-from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.view import AdminView
-from pyramid.view import view_config
-from z3c.table.column import GetAttrColumn
-from zope.interface import implementer, Interface
-
-from pyams_zmi import _
-
-
-#
-# Utilities views and adapters
-#
-
-@viewlet_config(name='utilities.menu', layer=IAdminLayer, context=ISite, manager=IControlPanelMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=1)
-@viewletmanager_config(name='utilities.menu', layer=IAdminLayer, context=ISite, provides=IUtilitiesMenu)
-@implementer(IUtilitiesMenu)
-class UtilitiesMenuItem(MenuItem):
- """Utilities menu"""
-
- label = _("Utilities")
- icon_class = 'fa-codepen'
- url = '#utilities.html'
-
-
-@implementer(ITableWithActions)
-class UtilitiesTable(BaseTable):
- """Utilities table"""
-
- id = 'utilities_table'
- title = _("Site utilities")
-
- @property
- def data_attributes(self):
- attributes = super(UtilitiesTable, self).data_attributes
- attributes['table'] = {'data-ams-location': absolute_url(self.context, self.request),
- 'data-ams-delete-target': 'delete-utility.json'}
- return attributes
-
-
-@adapter_config(name='trash', context=(Interface, IAdminLayer, UtilitiesTable), provides=IColumn)
-class UtilitiesTrashColumn(TrashColumn):
- """Utilities trash column"""
-
- icon_hint = _("Delete utility")
- permission = MANAGE_SYSTEM_PERMISSION
-
- checker = lambda col, x: IOptionalUtility.providedBy(x)
-
-
-@adapter_config(context=(ISite, IAdminLayer, UtilitiesTable), provides=IValues)
-class UtilitiesValuesAdapter(ContextRequestViewAdapter):
- """Utilities values adapter"""
-
- @property
- def values(self):
- return list(self.context.getSiteManager().values())
-
-
-@pagelet_config(name='utilities.html', context=ISite, layer=IPyAMSLayer, permission=MANAGE_SYSTEM_PERMISSION)
-@implementer(IInnerPage)
-class UtilitiesView(AdminView, ContainerView):
- """Control panel view"""
-
- table_class = UtilitiesTable
-
- def __init__(self, context, request):
- super(UtilitiesView, self).__init__(context, request)
-
-
-@adapter_config(context=(ISite, IAdminLayer, UtilitiesView), provides=IPageHeader)
-class UtilitiesHeaderAdapter(DefaultPageHeaderAdapter):
- """Utilities header adapter"""
-
- icon_class = 'fa fa-fw fa-codepen'
-
-
-@view_config(name='delete-utility.json', context=ISite, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-def delete_utility(request):
- """Delete utility from site manager"""
- translate = request.localizer.translate
- name = request.params.get('object_name')
- if not name:
- return {'status': 'message',
- 'messagebox': {'status': 'error',
- 'content': translate(_("No provided object_name argument!"))}}
- manager = request.context.getSiteManager()
- if name not in manager:
- return {'status': 'message',
- 'messagebox': {'status': 'error',
- 'content': translate(_("Given utility name doesn't exist!"))}}
- del manager[name]
- return {'status': 'success'}
-
-
-#
-# Common registrations views and adapters
-#
-
-class IRegistrationsTable(Interface):
- """Registrations view marker interface"""
-
-
-@adapter_config(name='component', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
-class RegistrationsComponentColumn(GetAttrColumn):
- """Registrations component column"""
-
- _header = _("Component")
- weight = 1
-
- @property
- def header(self):
- return self.request.localizer.translate(self._header)
-
- def getValue(self, obj):
- component = obj.component
- if component is not None:
- name = getattr(component, '__name__', None)
- if not name:
- name = str(component.__class__)
- else:
- name = str(obj.factory)
- return escape(name)
-
-
-@adapter_config(name='interface', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
-class RegistrationsInterfaceColumn(GetAttrColumn):
- """Registrations interface column"""
-
- _header = _("Registered interface")
- weight = 5
-
- @property
- def header(self):
- return self.request.localizer.translate(self._header)
-
- def getValue(self, obj):
- return text_to_html(str(obj.provided))
-
-
-@adapter_config(name='name', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
-class RegistrationsNameColumn(GetAttrColumn):
- """Registrations name column"""
-
- _header = _("Name")
- weight = 10
-
- @property
- def header(self):
- return self.request.localizer.translate(self._header)
-
- def getValue(self, obj):
- return obj.name or _('< no name >')
-
-
-#
-# Local registrations views
-#
-
-@viewlet_config(name='local-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=1)
-class LocalRegistrationsMenuItem(MenuItem):
- """Local registrations menu"""
-
- label = _("Local registrations")
- url = '#local-registrations.html'
-
-
-@implementer(IRegistrationsTable)
-class LocalRegistrationsTable(BaseTable):
- """Local utilities registrations table"""
-
- id = 'local_registrations_table'
- title = _("Local utilities registrations")
-
- data_attributes = {}
-
-
-@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsTable), provides=IValues)
-class LocalRegistrationsValuesAdapter(ContextRequestViewAdapter):
- """Local utilities values adapter"""
-
- @property
- def values(self):
- return list(self.context.getSiteManager().registeredUtilities())
-
-
-@pagelet_config(name='local-registrations.html', context=ISite, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-@implementer(IInnerPage)
-class LocalRegistrationsView(AdminView, ContainerView):
- """Registrations view"""
-
- table_class = LocalRegistrationsTable
-
- def __init__(self, context, request):
- super(LocalRegistrationsView, self).__init__(context, request)
-
-
-@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IPageHeader)
-class LocalRegistrationsHeaderAdapter(DefaultPageHeaderAdapter):
- """Local registrations header adapter"""
-
- icon_class = 'fa fa-fw fa-codepen'
-
-
-@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IContentHelp)
-class LocalRegistrationsHelpAdapter(ContentHelp):
- """Local registrations help adapter"""
-
- header = _("Local registry utilities")
- message = _("""A local registry is a registry defining utilities stored into
-site's Object Database (ZODB).
-
-You can manage these utilities and modify their properties and site's behaviour without
-modifying the application.""")
- message_format = 'rest'
-
-
-#
-# Global registrations views
-#
-
-@viewlet_config(name='global-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=2)
-class GlobalRegistrationsMenuItem(MenuItem):
- """Global registrations menu"""
-
- label = _("Global registrations")
- url = '#global-registrations.html'
-
-
-@implementer(IRegistrationsTable)
-class GlobalRegistrationsTable(BaseTable):
- """Utilities global registrations table"""
-
- id = 'global_registrations_table'
- title = _("Global utilities registrations")
-
- data_attributes = {}
-
-
-@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsTable), provides=IValues)
-class GlobalRegistrationsValuesAdapter(ContextRequestViewAdapter):
- """Global utilities values adapter"""
-
- @property
- def values(self):
- return list(registered_utilities())
-
-
-@pagelet_config(name='global-registrations.html', context=ISite, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-@implementer(IInnerPage)
-class GlobalRegistrationsView(AdminView, ContainerView):
- """Global registrations view"""
-
- table_class = GlobalRegistrationsTable
-
- def __init__(self, context, request):
- super(GlobalRegistrationsView, self).__init__(context, request)
-
-
-@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IPageHeader)
-class GlobalRegistrationsHeaderAdapter(DefaultPageHeaderAdapter):
- """Global registrations header adapter"""
-
- icon_class = 'fa fa-fw fa-codepen'
-
-
-@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IContentHelp)
-class GlobalRegistrationsHelpAdapter(ContentHelp):
- """Global registrations help adapter"""
-
- header = _("Global registry utilities")
- message = _("""The global registry groups local utilities as well as utilities registered outside
-site's Object Database (ZODB).
-
-These utilities are declared statically (generally using include or ZCML directives) and can't be setup
-without modifying site configuration.""")
- message_format = 'rest'
--- a/src/pyams_zmi/extension.py Sun Mar 11 11:16:23 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-#
-# Copyright (c) 2008-2015 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 interfaces
-from pyams_skin.interfaces.extension import IGoogleTagManagerInfo, IGoogleAnalyticsInfo, IUserReportInfo
-from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
-from pyams_utils.interfaces.site import ISiteRoot
-from pyams_zmi.interfaces.menu import IPropertiesMenu
-from pyams_zmi.layer import IAdminLayer
-
-# import packages
-from pyams_form.form import AJAXEditForm
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.viewlet.menu import MenuItem
-from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminDialogEditForm
-from pyramid.view import view_config
-from z3c.form import field
-
-from pyams_zmi import _
-
-
-#
-# Google Tag Manager views
-#
-
-@viewlet_config(name='tag-manager-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=10)
-class GoogleTagManagerPropertiesMenuItem(MenuItem):
- """Google Tag Manager properties menu"""
-
- label = _("Google Tag Manager...")
- icon_class = 'fa-tags'
- url = 'tag-manager-properties.html'
- modal_target = True
-
-
-@pagelet_config(name='tag-manager-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-class GoogleTagManagerPropertiesEditForm(AdminDialogEditForm):
- """Google Tag Manager properties edit form"""
-
- legend = _("Update Google Tag Manager properties")
- ajax_handler = 'tag-manager-properties.json'
- edit_permission = MANAGE_SYSTEM_PERMISSION
-
- fields = field.Fields(IGoogleTagManagerInfo)
-
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
-
-@view_config(name='tag-manager-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-class GoogleTagManagerPropertiesAJAXEditForm(AJAXEditForm, GoogleTagManagerPropertiesEditForm):
- """Google Tag Manager properties edit form, JSON renderer"""
-
-
-#
-# Google Analytics views
-#
-
-@viewlet_config(name='analytics-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=15)
-class GoogleAnalyticsPropertiesMenuItem(MenuItem):
- """Google Analytics properties menu"""
-
- label = _("Google Analytics...")
- icon_class = 'fa-line-chart'
- url = 'analytics-properties.html'
- modal_target = True
-
-
-@pagelet_config(name='analytics-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-class GoogleAnalyticsPropertiesEditForm(AdminDialogEditForm):
- """Google Analytics properties edit form"""
-
- legend = _("Update Google Analytics properties")
- ajax_handler = 'analytics-properties.json'
- edit_permission = MANAGE_SYSTEM_PERMISSION
-
- fields = field.Fields(IGoogleAnalyticsInfo)
-
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
-
-@view_config(name='analytics-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-class GoogleAnalyticsPropertiesAJAXEditForm(AJAXEditForm, GoogleAnalyticsPropertiesEditForm):
- """Google Analytics properties edit form, JSON renderer"""
-
-
-#
-# UserReport views
-#
-
-@viewlet_config(name='user-report.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=20)
-class UserReportPropertiesMenuItem(MenuItem):
- """UserReport properties menu"""
-
- label = _("UserReport settings...")
- icon_class = 'fa-comments'
- url = 'user-report.html'
- modal_target = True
-
-
-@pagelet_config(name='user-report.html', context=ISiteRoot, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-class UserReportPropertiesEditForm(AdminDialogEditForm):
- """UserReport properties edit form"""
-
- legend = _("Update UserReport service properties")
- ajax_handler = 'user-report.json'
- edit_permission = MANAGE_SYSTEM_PERMISSION
-
- fields = field.Fields(IUserReportInfo)
-
- label_css_class = 'control-label col-md-4'
- input_css_class = 'col-md-8'
-
-
-@view_config(name='user-report.json', context=ISiteRoot, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-class UserReportPropertiesAJAXEditForm(AJAXEditForm, UserReportPropertiesEditForm):
- """UserReport properties edit form, JSON renderer"""
--- a/src/pyams_zmi/site.py Sun Mar 11 11:16:23 2018 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-#
-# Copyright (c) 2008-2015 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 interfaces
-from pyams_form.interfaces.form import IWidgetForm
-from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentTitle
-from pyams_skin.interfaces.configuration import IConfiguration, IBackOfficeConfiguration
-from pyams_skin.layer import IPyAMSLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
-from pyams_utils.interfaces.site import ISiteRoot
-from pyams_zmi.interfaces.menu import ISiteManagementMenu, IPropertiesMenu
-from pyams_zmi.layer import IAdminLayer
-
-# import packages
-from pyams_form.form import AJAXEditForm
-from pyams_pagelet.pagelet import pagelet_config
-from pyams_skin.page import DefaultPageHeaderAdapter
-from pyams_skin.viewlet.menu import MenuItem
-from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
-from pyams_viewlet.manager import viewletmanager_config
-from pyams_viewlet.viewlet import viewlet_config
-from pyams_zmi.form import AdminEditForm, AdminDialogEditForm
-from pyramid.decorator import reify
-from pyramid.view import view_config
-from z3c.form import field
-from zope.interface import implementer, implementedBy, Interface
-
-from pyams_zmi import _
-
-
-@adapter_config(context=(ISiteRoot, IAdminLayer, Interface), provides=IContentTitle)
-class SiteRootTitleAdapter(ContextRequestViewAdapter):
- """Site root title adapter"""
-
- @property
- def title(self):
- return IBackOfficeConfiguration(self.context).title
-
-
-#
-# Configuration properties
-#
-
-@viewlet_config(name='properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=ISiteManagementMenu,
- permission=VIEW_SYSTEM_PERMISSION, weight=1)
-@viewletmanager_config(name='properties.menu', context=ISiteRoot, layer=IAdminLayer, provides=IPropertiesMenu)
-@implementer(IPropertiesMenu)
-class PropertiesMenuItem(MenuItem):
- """Properties menu"""
-
- label = _("Properties")
- icon_class = 'fa-edit'
- url = '#properties.html'
-
-
-@pagelet_config(name='properties.html', context=ISiteRoot, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
-@implementer(IWidgetForm, IInnerPage)
-class PropertiesEditForm(AdminEditForm):
- """Properties edit form"""
-
- legend = _("Update main site properties")
- ajax_handler = 'properties.json'
- edit_permission = MANAGE_SYSTEM_PERMISSION
-
- @reify
- def fields(self):
-
- def get_configuration_interface(context):
- for interface in implementedBy(context.__class__).interfaces():
- if issubclass(interface, IConfiguration):
- return interface
-
- content = self.getContent()
- return field.Fields(get_configuration_interface(content)).omit('__name__')
-
- def getContent(self):
- return IConfiguration(self.context)
-
-
-@view_config(name='properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-class PropertiesAJAXEditForm(AJAXEditForm, PropertiesEditForm):
- """Properties edit form, AJAX renderer"""
-
- def get_ajax_output(self, changes):
- if changes:
- return {'status': 'reload',
- 'location': '#properties.html',
- 'smallbox': self.request.localizer.translate(self.successMessage),
- 'smallbox_status': 'success'}
- else:
- return AJAXEditForm.get_ajax_output(self, changes)
-
-
-@adapter_config(context=(Interface, IPyAMSLayer, PropertiesEditForm), provides=IPageHeader)
-class PropertiesEditFormHeaderAdapter(DefaultPageHeaderAdapter):
- """Utilities header adapter"""
-
- @property
- def title(self):
- return IBackOfficeConfiguration(self.context).title
-
- icon_class = 'fa fa-fw fa-twitch'
-
-
-#
-# Back-office configuration properties
-#
-
-@viewlet_config(name='back-office-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
- permission=MANAGE_SYSTEM_PERMISSION, weight=1)
-class BackOfficePropertiesMenuItem(MenuItem):
- """Back-office properties menu"""
-
- label = _("Back-office properties...")
- icon_class = 'fa-tachometer'
- url = 'back-office-properties.html'
- modal_target = True
-
-
-@pagelet_config(name='back-office-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION)
-class BackOfficePropertiesEditForm(AdminDialogEditForm):
- """Back-office properties edit form"""
-
- legend = _("Update site back-office properties")
- ajax_handler = 'back-office-properties.json'
- edit_permission = MANAGE_SYSTEM_PERMISSION
-
- dialog_class = 'modal-large'
-
- @reify
- def fields(self):
-
- def get_configuration_interface(context):
- for interface in implementedBy(context.__class__).interfaces():
- if issubclass(interface, IBackOfficeConfiguration):
- return interface
-
- content = self.getContent()
- return field.Fields(get_configuration_interface(content)).omit('__name__')
-
- def getContent(self):
- return IBackOfficeConfiguration(self.context)
-
- def updateWidgets(self, prefix=None):
- super(BackOfficePropertiesEditForm, self).updateWidgets(prefix)
- if 'login_header' in self.widgets:
- self.widgets['login_header'].widget_css_class = 'textarea'
- if 'login_footer' in self.widgets:
- self.widgets['login_footer'].widget_css_class = 'textarea'
-
-
-@view_config(name='back-office-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
- permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
-class BackOfficePropertiesAJAXEditForm(AJAXEditForm, BackOfficePropertiesEditForm):
- """Back-office properties edit form, JSON renderer"""
-
- def get_ajax_output(self, changes):
- if changes:
- return {'status': 'reload',
- 'location': '#properties.html',
- 'smallbox': self.request.localizer.translate(self.successMessage),
- 'smallbox_status': 'success'}
- else:
- return AJAXEditForm.get_ajax_output(self, changes)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/__init__.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,19 @@
+#
+# 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 interfaces
+
+# import packages
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/control_panel.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,323 @@
+#
+# Copyright (c) 2008-2015 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
+from html import escape
+
+# import interfaces
+from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentHelp
+from pyams_skin.interfaces.container import ITableWithActions
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
+from pyams_utils.interfaces.site import IOptionalUtility
+from pyams_zmi.interfaces.menu import IControlPanelMenu, IUtilitiesMenu
+from pyams_zmi.layer import IAdminLayer
+from z3c.table.interfaces import IValues, IColumn
+from zope.component.interfaces import ISite
+
+# import packages
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.container import ContainerView
+from pyams_skin.help import ContentHelp
+from pyams_skin.page import DefaultPageHeaderAdapter
+from pyams_skin.table import BaseTable, TrashColumn
+from pyams_skin.viewlet.menu import MenuItem
+from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
+from pyams_utils.registry import registered_utilities
+from pyams_utils.text import text_to_html
+from pyams_utils.url import absolute_url
+from pyams_viewlet.manager import viewletmanager_config
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.view import AdminView
+from pyramid.view import view_config
+from z3c.table.column import GetAttrColumn
+from zope.interface import implementer, Interface
+
+from pyams_zmi import _
+
+
+#
+# Utilities views and adapters
+#
+
+@viewlet_config(name='utilities.menu', layer=IAdminLayer, context=ISite, manager=IControlPanelMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=1)
+@viewletmanager_config(name='utilities.menu', layer=IAdminLayer, context=ISite, provides=IUtilitiesMenu)
+@implementer(IUtilitiesMenu)
+class UtilitiesMenuItem(MenuItem):
+ """Utilities menu"""
+
+ label = _("Utilities")
+ icon_class = 'fa-codepen'
+ url = '#utilities.html'
+
+
+@implementer(ITableWithActions)
+class UtilitiesTable(BaseTable):
+ """Utilities table"""
+
+ id = 'utilities_table'
+ title = _("Site utilities")
+
+ @property
+ def data_attributes(self):
+ attributes = super(UtilitiesTable, self).data_attributes
+ attributes['table'] = {'data-ams-location': absolute_url(self.context, self.request),
+ 'data-ams-delete-target': 'delete-utility.json'}
+ return attributes
+
+
+@adapter_config(name='trash', context=(Interface, IAdminLayer, UtilitiesTable), provides=IColumn)
+class UtilitiesTrashColumn(TrashColumn):
+ """Utilities trash column"""
+
+ icon_hint = _("Delete utility")
+ permission = MANAGE_SYSTEM_PERMISSION
+
+ checker = lambda col, x: IOptionalUtility.providedBy(x)
+
+
+@adapter_config(context=(ISite, IAdminLayer, UtilitiesTable), provides=IValues)
+class UtilitiesValuesAdapter(ContextRequestViewAdapter):
+ """Utilities values adapter"""
+
+ @property
+ def values(self):
+ return list(self.context.getSiteManager().values())
+
+
+@pagelet_config(name='utilities.html', context=ISite, layer=IPyAMSLayer, permission=MANAGE_SYSTEM_PERMISSION)
+@implementer(IInnerPage)
+class UtilitiesView(AdminView, ContainerView):
+ """Control panel view"""
+
+ table_class = UtilitiesTable
+
+ def __init__(self, context, request):
+ super(UtilitiesView, self).__init__(context, request)
+
+
+@adapter_config(context=(ISite, IAdminLayer, UtilitiesView), provides=IPageHeader)
+class UtilitiesHeaderAdapter(DefaultPageHeaderAdapter):
+ """Utilities header adapter"""
+
+ icon_class = 'fa fa-fw fa-codepen'
+
+
+@view_config(name='delete-utility.json', context=ISite, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+def delete_utility(request):
+ """Delete utility from site manager"""
+ translate = request.localizer.translate
+ name = request.params.get('object_name')
+ if not name:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("No provided object_name argument!"))}}
+ manager = request.context.getSiteManager()
+ if name not in manager:
+ return {'status': 'message',
+ 'messagebox': {'status': 'error',
+ 'content': translate(_("Given utility name doesn't exist!"))}}
+ del manager[name]
+ return {'status': 'success'}
+
+
+#
+# Common registrations views and adapters
+#
+
+class IRegistrationsTable(Interface):
+ """Registrations view marker interface"""
+
+
+@adapter_config(name='component', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
+class RegistrationsComponentColumn(GetAttrColumn):
+ """Registrations component column"""
+
+ _header = _("Component")
+ weight = 1
+
+ @property
+ def header(self):
+ return self.request.localizer.translate(self._header)
+
+ def getValue(self, obj):
+ component = obj.component
+ if component is not None:
+ name = getattr(component, '__name__', None)
+ if not name:
+ name = str(component.__class__)
+ else:
+ name = str(obj.factory)
+ return escape(name)
+
+
+@adapter_config(name='interface', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
+class RegistrationsInterfaceColumn(GetAttrColumn):
+ """Registrations interface column"""
+
+ _header = _("Registered interface")
+ weight = 5
+
+ @property
+ def header(self):
+ return self.request.localizer.translate(self._header)
+
+ def getValue(self, obj):
+ return text_to_html(str(obj.provided))
+
+
+@adapter_config(name='name', context=(ISite, IAdminLayer, IRegistrationsTable), provides=IColumn)
+class RegistrationsNameColumn(GetAttrColumn):
+ """Registrations name column"""
+
+ _header = _("Name")
+ weight = 10
+
+ @property
+ def header(self):
+ return self.request.localizer.translate(self._header)
+
+ def getValue(self, obj):
+ return obj.name or _('< no name >')
+
+
+#
+# Local registrations views
+#
+
+@viewlet_config(name='local-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=1)
+class LocalRegistrationsMenuItem(MenuItem):
+ """Local registrations menu"""
+
+ label = _("Local registrations")
+ url = '#local-registrations.html'
+
+
+@implementer(IRegistrationsTable)
+class LocalRegistrationsTable(BaseTable):
+ """Local utilities registrations table"""
+
+ id = 'local_registrations_table'
+ title = _("Local utilities registrations")
+
+ data_attributes = {}
+
+
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsTable), provides=IValues)
+class LocalRegistrationsValuesAdapter(ContextRequestViewAdapter):
+ """Local utilities values adapter"""
+
+ @property
+ def values(self):
+ return list(self.context.getSiteManager().registeredUtilities())
+
+
+@pagelet_config(name='local-registrations.html', context=ISite, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+@implementer(IInnerPage)
+class LocalRegistrationsView(AdminView, ContainerView):
+ """Registrations view"""
+
+ table_class = LocalRegistrationsTable
+
+ def __init__(self, context, request):
+ super(LocalRegistrationsView, self).__init__(context, request)
+
+
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IPageHeader)
+class LocalRegistrationsHeaderAdapter(DefaultPageHeaderAdapter):
+ """Local registrations header adapter"""
+
+ icon_class = 'fa fa-fw fa-codepen'
+
+
+@adapter_config(context=(ISite, IAdminLayer, LocalRegistrationsView), provides=IContentHelp)
+class LocalRegistrationsHelpAdapter(ContentHelp):
+ """Local registrations help adapter"""
+
+ header = _("Local registry utilities")
+ message = _("""A local registry is a registry defining utilities stored into
+site's Object Database (ZODB).
+
+You can manage these utilities and modify their properties and site's behaviour without
+modifying the application.""")
+ message_format = 'rest'
+
+
+#
+# Global registrations views
+#
+
+@viewlet_config(name='global-registrations.menu', layer=IAdminLayer, context=ISite, manager=IUtilitiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=2)
+class GlobalRegistrationsMenuItem(MenuItem):
+ """Global registrations menu"""
+
+ label = _("Global registrations")
+ url = '#global-registrations.html'
+
+
+@implementer(IRegistrationsTable)
+class GlobalRegistrationsTable(BaseTable):
+ """Utilities global registrations table"""
+
+ id = 'global_registrations_table'
+ title = _("Global utilities registrations")
+
+ data_attributes = {}
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsTable), provides=IValues)
+class GlobalRegistrationsValuesAdapter(ContextRequestViewAdapter):
+ """Global utilities values adapter"""
+
+ @property
+ def values(self):
+ return list(registered_utilities())
+
+
+@pagelet_config(name='global-registrations.html', context=ISite, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+@implementer(IInnerPage)
+class GlobalRegistrationsView(AdminView, ContainerView):
+ """Global registrations view"""
+
+ table_class = GlobalRegistrationsTable
+
+ def __init__(self, context, request):
+ super(GlobalRegistrationsView, self).__init__(context, request)
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IPageHeader)
+class GlobalRegistrationsHeaderAdapter(DefaultPageHeaderAdapter):
+ """Global registrations header adapter"""
+
+ icon_class = 'fa fa-fw fa-codepen'
+
+
+@adapter_config(context=(ISite, IAdminLayer, GlobalRegistrationsView), provides=IContentHelp)
+class GlobalRegistrationsHelpAdapter(ContentHelp):
+ """Global registrations help adapter"""
+
+ header = _("Global registry utilities")
+ message = _("""The global registry groups local utilities as well as utilities registered outside
+site's Object Database (ZODB).
+
+These utilities are declared statically (generally using include or ZCML directives) and can't be setup
+without modifying site configuration.""")
+ message_format = 'rest'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/extension.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,149 @@
+#
+# Copyright (c) 2008-2015 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 interfaces
+from pyams_skin.interfaces.extension import IGoogleTagManagerInfo, IGoogleAnalyticsInfo, IUserReportInfo
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import MANAGE_SYSTEM_PERMISSION
+from pyams_utils.interfaces.site import ISiteRoot
+from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+
+# import packages
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.viewlet.menu import MenuItem, MenuDivider
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogEditForm
+from pyramid.view import view_config
+from z3c.form import field
+
+from pyams_zmi import _
+
+
+@viewlet_config(name='extensions-divider.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=9)
+class ExtensionsMenuDivider(MenuDivider):
+ """Extensions menu divider"""
+
+
+#
+# Google Tag Manager views
+#
+
+@viewlet_config(name='tag-manager-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=10)
+class GoogleTagManagerPropertiesMenuItem(MenuItem):
+ """Google Tag Manager properties menu"""
+
+ label = _("Google Tag Manager...")
+ icon_class = 'fa-tags'
+ url = 'tag-manager-properties.html'
+ modal_target = True
+
+
+@pagelet_config(name='tag-manager-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+class GoogleTagManagerPropertiesEditForm(AdminDialogEditForm):
+ """Google Tag Manager properties edit form"""
+
+ legend = _("Update Google Tag Manager properties")
+ ajax_handler = 'tag-manager-properties.json'
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ fields = field.Fields(IGoogleTagManagerInfo)
+
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+
+@view_config(name='tag-manager-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class GoogleTagManagerPropertiesAJAXEditForm(AJAXEditForm, GoogleTagManagerPropertiesEditForm):
+ """Google Tag Manager properties edit form, JSON renderer"""
+
+
+#
+# Google Analytics views
+#
+
+@viewlet_config(name='analytics-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=15)
+class GoogleAnalyticsPropertiesMenuItem(MenuItem):
+ """Google Analytics properties menu"""
+
+ label = _("Google Analytics...")
+ icon_class = 'fa-line-chart'
+ url = 'analytics-properties.html'
+ modal_target = True
+
+
+@pagelet_config(name='analytics-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+class GoogleAnalyticsPropertiesEditForm(AdminDialogEditForm):
+ """Google Analytics properties edit form"""
+
+ legend = _("Update Google Analytics properties")
+ ajax_handler = 'analytics-properties.json'
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ fields = field.Fields(IGoogleAnalyticsInfo)
+
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+
+@view_config(name='analytics-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class GoogleAnalyticsPropertiesAJAXEditForm(AJAXEditForm, GoogleAnalyticsPropertiesEditForm):
+ """Google Analytics properties edit form, JSON renderer"""
+
+
+#
+# UserReport views
+#
+
+@viewlet_config(name='user-report.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=20)
+class UserReportPropertiesMenuItem(MenuItem):
+ """UserReport properties menu"""
+
+ label = _("UserReport settings...")
+ icon_class = 'fa-comments'
+ url = 'user-report.html'
+ modal_target = True
+
+
+@pagelet_config(name='user-report.html', context=ISiteRoot, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+class UserReportPropertiesEditForm(AdminDialogEditForm):
+ """UserReport properties edit form"""
+
+ legend = _("Update UserReport service properties")
+ ajax_handler = 'user-report.json'
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ fields = field.Fields(IUserReportInfo)
+
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+
+@view_config(name='user-report.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class UserReportPropertiesAJAXEditForm(AJAXEditForm, UserReportPropertiesEditForm):
+ """UserReport properties edit form, JSON renderer"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/index.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2008-2015 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 interfaces
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
+from pyams_zmi.layer import IAdminLayer
+
+# import packages
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_template.template import template_config
+from pyams_zmi.view import AdminView
+from zope.interface import Interface
+
+
+@pagelet_config(name='admin', context=Interface, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+@template_config(template='templates/admin-index.pt', layer=IAdminLayer)
+class MainAdminPage(AdminView):
+ """Main administration page"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/site.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,223 @@
+#
+# Copyright (c) 2008-2015 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 interfaces
+from pyams_form.interfaces.form import IWidgetForm
+from pyams_skin.interfaces import IInnerPage, IPageHeader, IContentTitle
+from pyams_skin.interfaces.configuration import IConfiguration, IBackOfficeConfiguration
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION, MANAGE_SYSTEM_PERMISSION
+from pyams_utils.interfaces.site import ISiteRoot
+from pyams_zmi.interfaces import IZMIConfiguration
+from pyams_zmi.interfaces.menu import ISiteManagementMenu, IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+
+# import packages
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.page import DefaultPageHeaderAdapter
+from pyams_skin.viewlet.menu import MenuItem
+from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
+from pyams_viewlet.manager import viewletmanager_config
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminEditForm, AdminDialogEditForm
+from pyramid.decorator import reify
+from pyramid.view import view_config
+from z3c.form import field
+from zope.interface import implementer, implementedBy, Interface
+
+from pyams_zmi import _
+
+
+@adapter_config(context=(ISiteRoot, IAdminLayer, Interface), provides=IContentTitle)
+class SiteRootTitleAdapter(ContextRequestViewAdapter):
+ """Site root title adapter"""
+
+ @property
+ def title(self):
+ return IBackOfficeConfiguration(self.context).title
+
+
+#
+# Configuration properties
+#
+
+@viewlet_config(name='properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=ISiteManagementMenu,
+ permission=VIEW_SYSTEM_PERMISSION, weight=1)
+@viewletmanager_config(name='properties.menu', context=ISiteRoot, layer=IAdminLayer, provides=IPropertiesMenu)
+@implementer(IPropertiesMenu)
+class PropertiesMenuItem(MenuItem):
+ """Properties menu"""
+
+ label = _("Properties")
+ icon_class = 'fa-edit'
+ url = '#properties.html'
+
+
+@pagelet_config(name='properties.html', context=ISiteRoot, layer=IPyAMSLayer, permission=VIEW_SYSTEM_PERMISSION)
+@implementer(IWidgetForm, IInnerPage)
+class PropertiesEditForm(AdminEditForm):
+ """Properties edit form"""
+
+ legend = _("Update main site properties")
+ ajax_handler = 'properties.json'
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ @reify
+ def fields(self):
+
+ def get_configuration_interface(context):
+ for interface in implementedBy(context.__class__).interfaces():
+ if issubclass(interface, IConfiguration):
+ return interface
+
+ content = self.getContent()
+ return field.Fields(get_configuration_interface(content)).omit('__name__')
+
+ def getContent(self):
+ return IConfiguration(self.context)
+
+
+@view_config(name='properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class PropertiesAJAXEditForm(AJAXEditForm, PropertiesEditForm):
+ """Properties edit form, AJAX renderer"""
+
+ def get_ajax_output(self, changes):
+ if changes:
+ return {'status': 'reload',
+ 'location': '#properties.html',
+ 'smallbox': self.request.localizer.translate(self.successMessage),
+ 'smallbox_status': 'success'}
+ else:
+ return AJAXEditForm.get_ajax_output(self, changes)
+
+
+@adapter_config(context=(Interface, IPyAMSLayer, PropertiesEditForm), provides=IPageHeader)
+class PropertiesEditFormHeaderAdapter(DefaultPageHeaderAdapter):
+ """Utilities header adapter"""
+
+ @property
+ def title(self):
+ return IBackOfficeConfiguration(self.context).title
+
+ icon_class = 'fa fa-fw fa-twitch'
+
+
+#
+# Back-office configuration properties
+#
+
+@viewlet_config(name='back-office-properties.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=1)
+class BackOfficePropertiesMenuItem(MenuItem):
+ """Back-office properties menu"""
+
+ label = _("Back-office properties...")
+ icon_class = 'fa-tachometer'
+ url = 'back-office-properties.html'
+ modal_target = True
+
+
+@pagelet_config(name='back-office-properties.html', context=ISiteRoot, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+class BackOfficePropertiesEditForm(AdminDialogEditForm):
+ """Back-office properties edit form"""
+
+ legend = _("Update site back-office properties")
+ ajax_handler = 'back-office-properties.json'
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ dialog_class = 'modal-large'
+
+ @reify
+ def fields(self):
+
+ def get_configuration_interface(context):
+ for interface in implementedBy(context.__class__).interfaces():
+ if issubclass(interface, IBackOfficeConfiguration):
+ return interface
+
+ content = self.getContent()
+ return field.Fields(get_configuration_interface(content)).omit('__name__')
+
+ def getContent(self):
+ return IBackOfficeConfiguration(self.context)
+
+ def updateWidgets(self, prefix=None):
+ super(BackOfficePropertiesEditForm, self).updateWidgets(prefix)
+ if 'login_header' in self.widgets:
+ self.widgets['login_header'].widget_css_class = 'textarea'
+ if 'login_footer' in self.widgets:
+ self.widgets['login_footer'].widget_css_class = 'textarea'
+
+
+@view_config(name='back-office-properties.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class BackOfficePropertiesAJAXEditForm(AJAXEditForm, BackOfficePropertiesEditForm):
+ """Back-office properties edit form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ if changes:
+ return {'status': 'reload',
+ 'location': '#properties.html',
+ 'smallbox': self.request.localizer.translate(self.successMessage),
+ 'smallbox_status': 'success'}
+ else:
+ return AJAXEditForm.get_ajax_output(self, changes)
+
+
+#
+# ZMI configuration properties
+#
+
+@viewlet_config(name='zmi-configuration.menu', context=ISiteRoot, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SYSTEM_PERMISSION, weight=2)
+class ZMIConfigurationMenuItem(MenuItem):
+ """ZMI configuration menu"""
+
+ label = _("ZMI configuration...")
+ icon_class = 'fa-window-restore'
+ url = 'zmi-configuration.html'
+ modal_target = True
+
+
+@pagelet_config(name='zmi-configuration.html', context=ISiteRoot, layer=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION)
+class ZMIConfigurationEditForm(AdminDialogEditForm):
+ """ZMI configuration edit form"""
+
+ legend = _("Update ZMI configuration")
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ ajax_handler = "zmi-configuration.json"
+ edit_permission = MANAGE_SYSTEM_PERMISSION
+
+ fields = field.Fields(IZMIConfiguration)
+
+
+@view_config(name='zmi-configuration.json', context=ISiteRoot, request_type=IPyAMSLayer,
+ permission=MANAGE_SYSTEM_PERMISSION, renderer='json', xhr=True)
+class ZMIConfigurationAJAXEditForm(AJAXEditForm, ZMIConfigurationEditForm):
+ """ZMI configuration edit form, JSON renderer"""
+
+ def get_ajax_output(self, changes):
+ if changes:
+ return {'status': 'redirect'}
+ else:
+ return super(ZMIConfigurationAJAXEditForm, self).get_ajax_output(changes)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_zmi/zmi/skin.py Sun Mar 11 11:16:42 2018 +0100
@@ -0,0 +1,81 @@
+#
+# Copyright (c) 2008-2015 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 interfaces
+from pyams_skin.interfaces import IUserSkinnable
+from pyams_skin.layer import IPyAMSLayer
+from pyams_utils.interfaces import MANAGE_SKIN_PERMISSION
+from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+
+# import packages
+from pyams_form.form import AJAXEditForm
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.viewlet.menu import MenuItem, MenuDivider
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogEditForm
+from pyramid.view import view_config
+from z3c.form import field
+
+from pyams_zmi import _
+
+
+#
+# User skinnable properties configuration
+#
+
+@viewlet_config(name='user-skin-properties.divider', context=IUserSkinnable, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SKIN_PERMISSION, weight=199)
+class UserSkinnablePropertiesMenuDivider(MenuDivider):
+ """User skin properties menu divider"""
+
+
+@viewlet_config(name='user-skin-properties.menu', context=IUserSkinnable, layer=IAdminLayer, manager=IPropertiesMenu,
+ permission=MANAGE_SKIN_PERMISSION, weight=200)
+class UserSkinnablePropertiesMenuItem(MenuItem):
+ """User skin properties menu"""
+
+ label = _("Graphic theme...")
+ icon_class = 'fa-paint-brush'
+ url = 'user-skin-properties.html'
+ modal_target = True
+
+
+@pagelet_config(name='user-skin-properties.html', context=IUserSkinnable, layer=IPyAMSLayer,
+ permission=MANAGE_SKIN_PERMISSION)
+class UserSkinnablePropertiesEditForm(AdminDialogEditForm):
+ """User skin properties edit form"""
+
+ legend = _("Graphic theme elements")
+ label_css_class = 'control-label col-md-4'
+ input_css_class = 'col-md-8'
+
+ @property
+ def fields(self):
+ fields = field.Fields(IUserSkinnable)
+ if not self.context.can_inherit_skin:
+ fields = fields.omit('inherit_skin')
+ return fields
+
+ ajax_handler = 'user-skin-properties.json'
+ edit_permission = MANAGE_SKIN_PERMISSION
+
+
+@view_config(name='user-skin-properties.json', context=IUserSkinnable, request_type=IPyAMSLayer,
+ permission=MANAGE_SKIN_PERMISSION, renderer='json', xhr=True)
+class UserSkinnablePropertiesAJAXEditForm(AJAXEditForm, UserSkinnablePropertiesEditForm):
+ """User skin properties edit form, JSON renderer"""