|
1 # |
|
2 # Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
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 |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 |
|
13 __docformat__ = 'restructuredtext' |
|
14 |
|
15 from z3c.form import field |
|
16 from zope.interface import Interface |
|
17 from zope.intid import IIntIds |
|
18 |
|
19 from pyams_content.features.search import ISearchFolder, SearchFolder |
|
20 from pyams_content.interfaces import MANAGE_SITE_PERMISSION |
|
21 from pyams_content.shared.common.zmi.summary import SharedContentDublinCoreSummary, SharedContentWorkflowHistorySummary, \ |
|
22 SharedContentWorkflowPublicationState |
|
23 from pyams_content.shared.site.interfaces import ISiteContainer |
|
24 from pyams_content.shared.site.zmi import SiteManagerFoldersSelectorFieldWidget |
|
25 from pyams_content.shared.site.zmi.folder import ISiteFolderAddFormFields |
|
26 from pyams_form.form import AJAXAddForm, ajax_config |
|
27 from pyams_form.interfaces.form import IInnerSubForm |
|
28 from pyams_i18n.interfaces import II18n, INegotiator |
|
29 from pyams_pagelet.pagelet import pagelet_config |
|
30 from pyams_security.zmi.interfaces import IObjectSecurityMenu |
|
31 from pyams_skin.interfaces import IContentTitle, IPageHeader |
|
32 from pyams_skin.interfaces.viewlet import IMenuHeader, IToolbarAddingMenu, IContextActions |
|
33 from pyams_skin.layer import IPyAMSLayer |
|
34 from pyams_skin.page import DefaultPageHeaderAdapter, HeaderContentProvider |
|
35 from pyams_skin.viewlet.toolbar import ToolbarMenuItem |
|
36 from pyams_utils.adapter import ContextRequestAdapter, ContextRequestViewAdapter, NullAdapter, adapter_config |
|
37 from pyams_utils.registry import get_utility |
|
38 from pyams_utils.unicode import translate_string |
|
39 from pyams_utils.url import absolute_url |
|
40 from pyams_viewlet.viewlet import contentprovider_config, viewlet_config |
|
41 from pyams_workflow.interfaces import IWorkflowPublicationInfo |
|
42 from pyams_zmi.form import AdminDialogAddForm |
|
43 from pyams_zmi.interfaces.menu import IContentManagementMenu |
|
44 from pyams_zmi.layer import IAdminLayer |
|
45 |
|
46 from pyams_content import _ |
|
47 |
|
48 |
|
49 @adapter_config(context=(ISearchFolder, IPyAMSLayer, Interface), provides=IPageHeader) |
|
50 class SearchFolderPropertiesHeaderAdapter(DefaultPageHeaderAdapter): |
|
51 """Search folder header adapter""" |
|
52 |
|
53 back_url = '/admin#properties.html' |
|
54 back_target = None |
|
55 |
|
56 icon_class = 'fa fa-fw fa-edit' |
|
57 |
|
58 |
|
59 @adapter_config(context=(ISearchFolder, IContentManagementMenu), provides=IMenuHeader) |
|
60 class SearchFolderContentMenuHeader(ContextRequestAdapter): |
|
61 """Search folder menu header adapter""" |
|
62 |
|
63 header = _("This search folder") |
|
64 |
|
65 |
|
66 @adapter_config(context=(ISearchFolder, IPyAMSLayer, Interface), provides=IContentTitle) |
|
67 class SearchFolderTitleAdapter(ContextRequestViewAdapter): |
|
68 """Search folder title adapter""" |
|
69 |
|
70 @property |
|
71 def title(self): |
|
72 translate = self.request.localizer.translate |
|
73 return translate(_("Search folder « {title} »")).format( |
|
74 title=II18n(self.context).query_attribute('title', request=self.request)) |
|
75 |
|
76 |
|
77 @viewlet_config(name='add-search-folder.menu', context=ISiteContainer, layer=IAdminLayer, view=Interface, |
|
78 manager=IToolbarAddingMenu, permission=MANAGE_SITE_PERMISSION, weight=11) |
|
79 class SearchFolderAddMenu(ToolbarMenuItem): |
|
80 """Search folder add menu""" |
|
81 |
|
82 label = _("Add search folder...") |
|
83 label_css_class = 'fa fa-fw fa-search' |
|
84 url = 'add-search-folder.html' |
|
85 modal_target = True |
|
86 |
|
87 |
|
88 @pagelet_config(name='add-search-folder.html', context=ISiteContainer, layer=IPyAMSLayer, |
|
89 permission=MANAGE_SITE_PERMISSION) |
|
90 @ajax_config(name='add-search-folder.json', context=ISiteContainer, layer=IPyAMSLayer, base=AJAXAddForm) |
|
91 class SearchFolderAddForm(AdminDialogAddForm): |
|
92 """Search folder add form""" |
|
93 |
|
94 @property |
|
95 def title(self): |
|
96 return II18n(self.context).query_attribute('title', request=self.request) |
|
97 |
|
98 legend = _("Add search folder") |
|
99 icon_css_class = 'fa fa-fw fa-search' |
|
100 |
|
101 fields = field.Fields(ISiteFolderAddFormFields) |
|
102 fields['parent'].widgetFactory = SiteManagerFoldersSelectorFieldWidget |
|
103 |
|
104 edit_permission = MANAGE_SITE_PERMISSION |
|
105 |
|
106 def updateWidgets(self, prefix=None): |
|
107 super(SearchFolderAddForm, self).updateWidgets(prefix) |
|
108 if 'parent' in self.widgets: |
|
109 self.widgets['parent'].permission = MANAGE_SITE_PERMISSION |
|
110 |
|
111 def create(self, data): |
|
112 return SearchFolder() |
|
113 |
|
114 def update_content(self, content, data): |
|
115 data = data.get(self, data) |
|
116 # initialize |
|
117 content.title = data['title'] |
|
118 content.short_name = data['title'] |
|
119 content.notepad = data['notepad'] |
|
120 intids = get_utility(IIntIds) |
|
121 parent = intids.queryObject(data.get('parent')) |
|
122 if parent is not None: |
|
123 negotiator = get_utility(INegotiator) |
|
124 title = II18n(content).get_attribute('title', lang=negotiator.server_language) |
|
125 name = translate_string(title, force_lower=True, spaces='-') |
|
126 if name in parent: |
|
127 index = 1 |
|
128 new_name = '{name}-{index:02}'.format(name=name, index=index) |
|
129 while new_name in parent: |
|
130 index += 1 |
|
131 new_name = '{name}-{index:02}'.format(name=name, index=index) |
|
132 name = new_name |
|
133 parent[name] = content |
|
134 |
|
135 def add(self, content): |
|
136 pass |
|
137 |
|
138 def nextURL(self): |
|
139 return absolute_url(self.context, self.request, 'admin#site-tree.html') |
|
140 |
|
141 def get_ajax_output(self, changes): |
|
142 return {'status': 'reload'} |
|
143 |
|
144 |
|
145 # |
|
146 # Search folder content providers |
|
147 # |
|
148 |
|
149 @contentprovider_config(name='content_header', context=ISearchFolder, view=Interface, layer=IPyAMSLayer) |
|
150 class SearchFolderHeaderContentProvider(HeaderContentProvider): |
|
151 """Search folder header content provider""" |
|
152 |
|
153 |
|
154 # |
|
155 # Custom search folders adapters |
|
156 # |
|
157 |
|
158 @adapter_config(name='workflow-publication-state', |
|
159 context=(ISearchFolder, IPyAMSLayer, SharedContentDublinCoreSummary), |
|
160 provides=IInnerSubForm) |
|
161 class SearchFolderWorkflowPublicationState(SharedContentWorkflowPublicationState): |
|
162 """Search folder workflow publication state is disabled""" |
|
163 |
|
164 fields = field.Fields(IWorkflowPublicationInfo).select('publication_effective_date', |
|
165 'publication_expiration_date') |
|
166 |
|
167 |
|
168 @adapter_config(name='workflow-history-summary', |
|
169 context=(ISearchFolder, IPyAMSLayer, SharedContentDublinCoreSummary), |
|
170 provides=IInnerSubForm) |
|
171 class SearchFolderWorkflowHistorySummary(SharedContentWorkflowHistorySummary): |
|
172 """Search folder workflow history summary""" |
|
173 |
|
174 fields = field.Fields(IWorkflowPublicationInfo).select('first_publication_date') |
|
175 |
|
176 |
|
177 @viewlet_config(name='change-owner.menu', context=ISearchFolder, layer=IPyAMSLayer, |
|
178 view=Interface, manager=IObjectSecurityMenu, permission=MANAGE_SITE_PERMISSION, weight=10) |
|
179 class SearchFolderOwnerChangeMenu(NullAdapter): |
|
180 """Search folder owner change menu is disabled""" |
|
181 |
|
182 |
|
183 @viewlet_config(name='duplication.divider', context=ISearchFolder, layer=IPyAMSLayer, |
|
184 view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=49) |
|
185 class SearchFolderDuplicationMenuDivider(NullAdapter): |
|
186 """Search folder duplication menu divider is disabled""" |
|
187 |
|
188 |
|
189 @viewlet_config(name='duplication.menu', context=ISearchFolder, layer=IPyAMSLayer, |
|
190 view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=50) |
|
191 class SearchFolderDuplicateMenu(NullAdapter): |
|
192 """Search folder duplication menu item is disabled""" |
|
193 |
|
194 |
|
195 @viewlet_config(name='ask-review.menu', context=ISearchFolder, layer=IPyAMSLayer, |
|
196 view=Interface, manager=IContextActions, permission=MANAGE_SITE_PERMISSION, weight=10) |
|
197 class SearchFolderReviewMenu(NullAdapter): |
|
198 """Search folder review menu is disabled""" |