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!")),) |