src/pyams_portal/zmi/layout.py
changeset 147 7fb2efbf0b63
parent 140 95bee9c0ae3f
child 175 f91042366ca4
equal deleted inserted replaced
146:6e4da3ad6a67 147:7fb2efbf0b63
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
       
    12 from pyams_utils.unicode import translate_string
       
    13 from pyams_utils.url import absolute_url
    12 
    14 
    13 __docformat__ = 'restructuredtext'
    15 __docformat__ = 'restructuredtext'
    14 
    16 
    15 
    17 
    16 # import standard library
    18 # import standard library
    21 from pyams_portal.interfaces import IPortalTemplate, IPortalTemplateConfiguration, ISlot, \
    23 from pyams_portal.interfaces import IPortalTemplate, IPortalTemplateConfiguration, ISlot, \
    22     IPortletAddingInfo, IPortlet, ISlotConfiguration, IPortletPreviewer, IPortalTemplateContainer, \
    24     IPortletAddingInfo, IPortlet, ISlotConfiguration, IPortletPreviewer, IPortalTemplateContainer, \
    23     IPortalTemplateContainerConfiguration, IPortalPortletsConfiguration, IPortalContext, IPortalPage, \
    25     IPortalTemplateContainerConfiguration, IPortalPortletsConfiguration, IPortalContext, IPortalPage, \
    24     MANAGE_TEMPLATE_PERMISSION
    26     MANAGE_TEMPLATE_PERMISSION
    25 from pyams_skin.interfaces import IInnerPage, IPageHeader
    27 from pyams_skin.interfaces import IInnerPage, IPageHeader
    26 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IMenuHeader
    28 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IMenuHeader, IContextActions
    27 from pyams_skin.layer import IPyAMSLayer
    29 from pyams_skin.layer import IPyAMSLayer
    28 from pyams_zmi.interfaces.menu import IPropertiesMenu, IContentManagementMenu
    30 from pyams_zmi.interfaces.menu import IPropertiesMenu, IContentManagementMenu
    29 from pyams_zmi.layer import IAdminLayer
    31 from pyams_zmi.layer import IAdminLayer
    30 from transaction.interfaces import ITransactionManager
    32 from transaction.interfaces import ITransactionManager
    31 from z3c.form.interfaces import IDataExtractedEvent, HIDDEN_MODE
    33 from z3c.form.interfaces import IDataExtractedEvent, HIDDEN_MODE
    32 
    34 
    33 # import packages
    35 # import packages
    34 from pyams_cache.beaker import get_cache
    36 from pyams_cache.beaker import get_cache
    35 from pyams_form.form import AJAXAddForm, AJAXEditForm, ajax_config
    37 from pyams_form.form import AJAXAddForm, AJAXEditForm, ajax_config
       
    38 from pyams_form.schema import CloseButton
    36 from pyams_pagelet.pagelet import pagelet_config
    39 from pyams_pagelet.pagelet import pagelet_config
    37 from pyams_portal.portlet import PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME
    40 from pyams_portal.portlet import PORTLETS_CACHE_REGION, PORTLETS_CACHE_NAME
    38 from pyams_portal.zmi.template import PortalTemplateHeaderAdapter
    41 from pyams_portal.zmi.template import PortalTemplateHeaderAdapter
    39 from pyams_skin.viewlet.menu import MenuItem
    42 from pyams_skin.viewlet.menu import MenuItem
    40 from pyams_skin.viewlet.toolbar import JsToolbarMenuItem, ToolbarMenuDivider, ToolbarMenuItem
    43 from pyams_skin.viewlet.toolbar import JsToolbarMenuItem, ToolbarMenuDivider, ToolbarMenuItem
    41 from pyams_template.template import template_config
    44 from pyams_template.template import template_config
    42 from pyams_utils.adapter import adapter_config
    45 from pyams_utils.adapter import adapter_config
    43 from pyams_utils.registry import query_utility
    46 from pyams_utils.registry import query_utility, get_utility
    44 from pyams_utils.traversing import get_parent
    47 from pyams_utils.traversing import get_parent
    45 from pyams_viewlet.manager import viewletmanager_config
    48 from pyams_viewlet.manager import viewletmanager_config
    46 from pyams_viewlet.viewlet import viewlet_config
    49 from pyams_viewlet.viewlet import viewlet_config
    47 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    50 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    48 from pyams_zmi.view import AdminView
    51 from pyams_zmi.view import AdminView
    49 from pyramid.decorator import reify
    52 from pyramid.decorator import reify
    50 from pyramid.events import subscriber
    53 from pyramid.events import subscriber
    51 from pyramid.exceptions import NotFound
    54 from pyramid.exceptions import NotFound
    52 from pyramid.view import view_config
    55 from pyramid.view import view_config
    53 from z3c.form import field
    56 from z3c.form import field, button
       
    57 from zope.copy import copy
    54 from zope.interface import implementer, Invalid, Interface
    58 from zope.interface import implementer, Invalid, Interface
    55 
    59 
    56 from pyams_portal import _
    60 from pyams_portal import _
    57 
    61 
    58 
    62 
   545 def delete_template_portlet(request):
   549 def delete_template_portlet(request):
   546     """Delete template portlet"""
   550     """Delete template portlet"""
   547     config = IPortalTemplateConfiguration(request.context)
   551     config = IPortalTemplateConfiguration(request.context)
   548     config.delete_portlet(int(request.params.get('portlet_id')))
   552     config.delete_portlet(int(request.params.get('portlet_id')))
   549     return {'status': 'success'}
   553     return {'status': 'success'}
       
   554 
       
   555 
       
   556 #
       
   557 # Portal template duplication form
       
   558 #
       
   559 
       
   560 @viewlet_config(name='duplication.divider', context=IPortalTemplate, layer=IPyAMSLayer,
       
   561                 view=PortalTemplateLayoutView, manager=IContextActions, permission=MANAGE_TEMPLATE_PERMISSION, weight=99)
       
   562 class PortalTemplateDuplicationMenuDivider(ToolbarMenuDivider):
       
   563     """Portal template duplication menu divider"""
       
   564 
       
   565     def __new__(cls, context, request, view, manager):
       
   566         container = get_parent(context, IPortalTemplateContainer)
       
   567         if container is None:
       
   568             return None
       
   569         return ToolbarMenuDivider.__new__(cls)
       
   570 
       
   571 
       
   572 @viewlet_config(name='duplication.menu', context=IPortalTemplate, layer=IPyAMSLayer,
       
   573                 view=PortalTemplateLayoutView, manager=IContextActions, permission=MANAGE_TEMPLATE_PERMISSION, weight=100)
       
   574 class PortalTemplateDuplicationMenu(ToolbarMenuItem):
       
   575     """Portal template duplication menu item"""
       
   576 
       
   577     def __new__(cls, context, request, view, manager):
       
   578         container = get_parent(context, IPortalTemplateContainer)
       
   579         if container is None:
       
   580             return None
       
   581         return ToolbarMenuDivider.__new__(cls)
       
   582 
       
   583     label = _("Duplicate template...")
       
   584     label_css_class = 'fa fa-fw fa-files-o'
       
   585 
       
   586     url = 'duplicate.html'
       
   587     modal_target = True
       
   588 
       
   589 
       
   590 class IPortalTemplateDuplicationButtons(Interface):
       
   591     """Portal template duplication form buttons"""
       
   592 
       
   593     close = CloseButton(name='close', title=_("Cancel"))
       
   594     duplicate = button.Button(name='duplicate', title=_("Duplicate this template"))
       
   595 
       
   596 
       
   597 @pagelet_config(name='duplicate.html', context=IPortalTemplate, layer=IPyAMSLayer,
       
   598                 permission=MANAGE_TEMPLATE_PERMISSION)
       
   599 @ajax_config(name='duplicate.json', context=IPortalTemplate, layer=IPyAMSLayer, base=AJAXAddForm)
       
   600 class PortalTemplateDuplicationForm(AdminDialogAddForm):
       
   601     """Portal template duplicate form"""
       
   602 
       
   603     legend = _("Duplicate template")
       
   604     icon_css_class = 'fa fa-fw fa-files-o'
       
   605 
       
   606     fields = field.Fields(IPortalTemplate)
       
   607     buttons = button.Buttons(IPortalTemplateDuplicationButtons)
       
   608 
       
   609     edit_permission = MANAGE_TEMPLATE_PERMISSION
       
   610 
       
   611     def updateWidgets(self, prefix=None):
       
   612         super(PortalTemplateDuplicationForm, self).updateWidgets(prefix)
       
   613         if 'name' in self.widgets:
       
   614             self.widgets['name'].label = _("New template name")
       
   615 
       
   616     def updateActions(self):
       
   617         super(PortalTemplateDuplicationForm, self).updateActions()
       
   618         if 'duplicate' in self.actions:
       
   619             self.actions['duplicate'].addClass('btn-primary')
       
   620 
       
   621     def create(self, data):
       
   622         return copy(self.context)
       
   623 
       
   624     def add(self, template):
       
   625         container = get_utility(IPortalTemplateContainer)
       
   626         container[translate_string(template.name, spaces='-')] = template
       
   627 
       
   628     def nextURL(self):
       
   629         return absolute_url(self.request.root, self.request, 'admin#portal-templates.html')
       
   630 
       
   631     def get_ajax_output(self, changes):
       
   632         return {
       
   633             'status': 'redirect',
       
   634             'location': self.nextURL()
       
   635         }
       
   636 
       
   637 
       
   638 @subscriber(IDataExtractedEvent, form_selector=PortalTemplateDuplicationForm)
       
   639 def handle_new_template_data_extraction(event):
       
   640     """Handle new template form data extraction"""
       
   641     container = get_utility(IPortalTemplateContainer)
       
   642     name = translate_string(event.data.get('name'), spaces='-')
       
   643     if name in container:
       
   644         event.form.widgets.errors += (Invalid(_("Specified name is already used!")),)