Wiki source code of Administration
Last modified by Julien Fleury on 2020/12/12 16:55
Show last authors
author | version | line-number | content |
---|---|---|---|
1 | {{include reference="XWiki.ConfigurableClassMacros" /}} | ||
2 | |||
3 | {{velocity output="false"}} | ||
4 | #if ($request.xaction == 'switchContext') | ||
5 | $response.sendRedirect($request.target) | ||
6 | #stop | ||
7 | #end | ||
8 | |||
9 | #set ($adminAction = 'admin') | ||
10 | #set ($crtCategoryId = "$!{request.category}") | ||
11 | #if ($crtCategoryId != '') | ||
12 | #set ($crtCategoryId = $numbertool.toNumber($crtCategoryId).intValue()) | ||
13 | #end | ||
14 | #set ($crtSectionId = "$!{request.section}") | ||
15 | |||
16 | ## | ||
17 | ## Admin menu map | ||
18 | ## | ||
19 | ## displayInSection: menu.name | sectionOrder: 200 | page: Menu.MenuConfigurationSection | ||
20 | ## displayInSection: panels.applications | sectionOrder: 400 | page: PanelsCode.ApplicationsPanelConfigurable | ||
21 | ## displayInSection: panels.navigation | sectionOrder: 500 | page: PanelsCode.NavigationConfigurationSection | ||
22 | #set($adminMenu = [ | ||
23 | { | ||
24 | 'id' : 'lf', | ||
25 | 'icon': 'columns', | ||
26 | 'displayBeforeCategory': 'content', | ||
27 | 'children': [ | ||
28 | {'id' : 'Themes', 'perSpace' : true, 'order' : 100}, | ||
29 | {'id' : 'Panels.PanelWizard', 'perSpace' : true, 'order' : 300}, | ||
30 | {'id' : 'Presentation', 'perSpace' : true, 'order' : 600} | ||
31 | ] | ||
32 | }, | ||
33 | { | ||
34 | 'id' : 'usersgroups', | ||
35 | 'icon': 'group', | ||
36 | 'displayBeforeCategory': 'extensionmanager', | ||
37 | 'children': [ | ||
38 | {'id' : 'Users', 'order' : 100}, | ||
39 | {'id' : 'Groups', 'order' : 200}, | ||
40 | {'id' : 'Rights', 'perSpace' : false, 'order' : 300}, | ||
41 | {'id' : 'PageAndChildrenRights', 'perSpace' : true, 'order' : 300, 'global': false}, | ||
42 | {'id' : 'PageRights', 'perSpace' : true, 'order' : 350, 'global': false}, | ||
43 | {'id' : 'UserProfile', 'order' : 400}, | ||
44 | {'id' : 'Registration', 'order' : 500} | ||
45 | ] | ||
46 | }, | ||
47 | { | ||
48 | 'id' : 'other', | ||
49 | 'icon': 'wrench', | ||
50 | 'children' : [] | ||
51 | } | ||
52 | ]) | ||
53 | |||
54 | ## | ||
55 | ## Fill in the list of custom applications to configure | ||
56 | ## | ||
57 | #findCustomSectionsToConfigure($adminMenu) | ||
58 | ## | ||
59 | ## Filter only the sections that are valid in the context | ||
60 | ## | ||
61 | #set ($categoriesToRemove = []) | ||
62 | #foreach ($category in $adminMenu) | ||
63 | #set ($sectionsToRemove = []) | ||
64 | #foreach ($section in $category.children) | ||
65 | #if ($editor == 'spaceadmin' && !$section.perSpace) | ||
66 | #set ($discard = $sectionsToRemove.add($section)) | ||
67 | #elseif ($editor == 'globaladmin' && "$!section.global" == "false") | ||
68 | ## For retro-compatibility, all sections are global unless the 'global' field is explicitly marked as false | ||
69 | #set ($discard = $sectionsToRemove.add($section)) | ||
70 | #end | ||
71 | #end | ||
72 | #set ($discard = $category.children.removeAll($sectionsToRemove)) | ||
73 | #if ($category.children.size() == 0) | ||
74 | #set ($discard = $categoriesToRemove.add($category)) | ||
75 | #end | ||
76 | #end | ||
77 | #set ($discard = $adminMenu.removeAll($categoriesToRemove)) | ||
78 | #if ("$!crtCategoryId" != '' && $crtCategoryId >= $adminMenu.size()) | ||
79 | #set ($crtCategoryId = '') | ||
80 | #end | ||
81 | |||
82 | ## | ||
83 | ## Prepare the Admin menu map for processing | ||
84 | ## | ||
85 | #set ($filteredAdminMenu = []) | ||
86 | #set ($crtSection = $NULL) | ||
87 | #set ($crtCategory = $NULL) | ||
88 | #foreach ($category in $adminMenu) | ||
89 | ## "Standard" URLs and icons for categories | ||
90 | #set ($category.url = $xwiki.getURL($currentDoc, $adminAction, "category=${mathtool.sub($foreach.count, 1)}")) | ||
91 | #if ($xwiki.getDocument('XWiki.AdminSheet').getAttachment("${category.id}.png")) | ||
92 | #set ($category.iconReference = "XWiki.AdminSheet@${category.id}.png") | ||
93 | #else | ||
94 | #set ($category.iconReference = "XWiki.ConfigurableClass@DefaultAdminSectionIcon.png") | ||
95 | #end | ||
96 | #set ($category.description = $services.localization.render("admin.${category.id}.description").trim()) | ||
97 | #set ($category.cssClass = "${category.id}Icon") | ||
98 | #set ($category.name = $services.localization.render("admin.${category.id}").trim()) | ||
99 | #if ("$!{crtCategoryId}" != '' && $foreach.count == $mathtool.add($crtCategoryId, 1)) | ||
100 | #set ($crtCategory = $category) | ||
101 | #end | ||
102 | ## | ||
103 | ## Process each admin section | ||
104 | #set ($filteredCategoryChildren = []) | ||
105 | #foreach ($section in $category.children) | ||
106 | #if ($xwiki.exists($section.id) || $xwiki.exists("XWiki.Admin${section.id}Sheet")) | ||
107 | #if ($crtSectionId == $section.id) | ||
108 | #set ($crtSection = $section) | ||
109 | #set ($crtCategory = $category) | ||
110 | #end | ||
111 | #set ($section.iconReference = '') | ||
112 | #if ($section.id.indexOf('.') > 0) | ||
113 | #set ($sectionDoc = $xwiki.getDocument($section.id)) | ||
114 | #set ($section.name = $sectionDoc.getDisplayTitle()) | ||
115 | #if ($sectionDoc.getAttachment('icon.png')) | ||
116 | #set ($section.iconReference = "${sectionDoc}@icon.png") | ||
117 | #else | ||
118 | #set ($section.iconReference = 'XWiki.ConfigurableClass@DefaultAdminSectionIcon.png') | ||
119 | #end | ||
120 | #else | ||
121 | #set ($sectionDoc = $xwiki.getDocument('XWiki.AdminSheet')) | ||
122 | #set ($section.name = $services.localization.render("admin.${section.id.toLowerCase()}")) | ||
123 | #set ($iconName = "${section.id.toLowerCase()}.png") | ||
124 | #if ($sectionDoc.getAttachment($iconName)) | ||
125 | #set ($section.iconReference = "${sectionDoc}@${iconName}") | ||
126 | #else | ||
127 | #set ($section.iconReference = 'XWiki.ConfigurableClass@DefaultAdminSectionIcon.png') | ||
128 | #end | ||
129 | #end | ||
130 | #set ($query = "editor=$escapetool.url(${editor})§ion=$escapetool.url(${section.id})") | ||
131 | #if ($editor != 'globaladmin') | ||
132 | #set ($query = $query + "&space=$escapetool.url(${currentSpace})") | ||
133 | #end | ||
134 | #set ($action = "$!{section.action}") | ||
135 | #if ($action == '') | ||
136 | #set ($action = $adminAction) | ||
137 | #end | ||
138 | #set ($section.url = $xwiki.getURL($currentDoc, $action, $query)) | ||
139 | #set ($key = "admin.${section.id.toLowerCase()}.description") | ||
140 | #if ($services.localization.get($key)) | ||
141 | #set ($section.description = $services.localization.render($key)) | ||
142 | #end | ||
143 | #set ($discard = $filteredCategoryChildren.add($section)) | ||
144 | #elseif ($section.configurable) | ||
145 | #if ($section.readOnly) | ||
146 | #set ($section.cssClass = 'readOnly') | ||
147 | #end | ||
148 | #if ($crtSectionId == $section.id) | ||
149 | #set ($crtSection = $section) | ||
150 | #set ($crtCategory = $category) | ||
151 | #end | ||
152 | #set ($discard = $filteredCategoryChildren.add($section)) | ||
153 | #end | ||
154 | #end | ||
155 | #set ($category.children = $filteredCategoryChildren) | ||
156 | #if ($filteredCategoryChildren.size() > 0) | ||
157 | #set ($discard = $filteredAdminMenu.add($category)) | ||
158 | #end | ||
159 | #end | ||
160 | #set ($adminMenu = $filteredAdminMenu) | ||
161 | |||
162 | ## Mark the active category/section. We use this flag when displaying the menu. | ||
163 | #if ($crtCategory) | ||
164 | #set ($crtCategory.active = true) | ||
165 | #if ($crtSection) | ||
166 | #set ($crtSection.active = true) | ||
167 | #else | ||
168 | #set ($crtSectionId = $NULL) | ||
169 | #end | ||
170 | #else | ||
171 | #set ($crtCategoryId = $NULL) | ||
172 | #end | ||
173 | |||
174 | #** | ||
175 | * Displays the sections from an administration category | ||
176 | * | ||
177 | * Expected format: | ||
178 | * sections = vector of items | ||
179 | * item = map with the following fields: | ||
180 | * 'id' : mandatory | ||
181 | * 'name' : the text displayed for the corresponding menu item; | ||
182 | * optional, defaults to | ||
183 | * $services.localization.render("$!{translationPrefix}${item.id}") | ||
184 | * 'description' : the description displayed for the corresponding section; | ||
185 | * optional | ||
186 | * 'link' : the "action" of the menu item; mandatory | ||
187 | * 'cssClass' : a specific css class for the menu item for custom | ||
188 | * styling; optional, defaults to '' | ||
189 | * | ||
190 | * @param $sections the sections list, in the format described above | ||
191 | * @param $translationPrefix the translation prefix added to the id of each | ||
192 | * item, in order to generate the name and description; ignored when | ||
193 | * name or description are specified | ||
194 | *# | ||
195 | #macro(admin_displayCategory $sections $translationPrefix) | ||
196 | (% class="admin-category" %) | ||
197 | #set ($sortedSections = []) | ||
198 | #sortCollectionOfMapsByField($sections, 'order', 9999, 'asc', $sortedSections) | ||
199 | #foreach ($section in $sortedSections) | ||
200 | * [[[[image:${section.iconReference}]] **${section.name}**>>path:${section.url}]] (% class="description" %)$!{section.description} | ||
201 | #end | ||
202 | #end | ||
203 | |||
204 | |||
205 | #** | ||
206 | * Displays the administration categories | ||
207 | * | ||
208 | * Expected format: | ||
209 | * sections = vector of items | ||
210 | * item = map with the following fields: | ||
211 | * 'id' : mandatory | ||
212 | * 'name' : the text displayed for the corresponding menu item; | ||
213 | * optional, defaults to | ||
214 | * $services.localization.render("$!{translationPrefix}${item.id}") | ||
215 | * 'description' : the description displayed for the corresponding section; | ||
216 | * optional | ||
217 | * 'link' : the "action" of the menu item; mandatory | ||
218 | * 'cssClass' : a specific css class for the menu item for custom | ||
219 | * styling; optional, defaults to '' | ||
220 | * | ||
221 | * @param $sections the sections list, in the format described above | ||
222 | * @param $translationPrefix the translation prefix added to the id of each | ||
223 | * item, in order to generate the name and description; ignored when | ||
224 | * name or description are specified | ||
225 | *# | ||
226 | #macro(admin_displayCategories $adminMenu $translationPrefix) | ||
227 | (% class="admin-category" %) | ||
228 | #foreach ($category in $adminMenu) | ||
229 | * [[[[image:${category.iconReference}]] **${category.name}**>>path:${category.url}]] (% class="description" %)$!{category.description} | ||
230 | #end | ||
231 | #end | ||
232 | |||
233 | #macro (verticalNavigation $menu $options) | ||
234 | {{html clean="false"}} | ||
235 | <div id="$!options.id" class="panel-group $!options.cssClass" role="tablist" aria-multiselectable="true"> | ||
236 | <div class="panel xform"> | ||
237 | <label for="adminsearchmenu" class="hidden">$services.localization.render('search')</label> | ||
238 | <input type="text" class="form-control panel-group-filter" autocomplete="off" id="adminsearchmenu" | ||
239 | placeholder="$escapetool.xml($services.localization.render('administration.menu.search.hint'))" | ||
240 | ## Disable the search input initially until the JavaScript code that handles the search is ready. | ||
241 | disabled="disabled" /> | ||
242 | </div> | ||
243 | #foreach ($item in $menu) | ||
244 | #verticalNavigationItem($item $options) | ||
245 | #end | ||
246 | <div class="panel panel-default noitems hidden"> | ||
247 | <div class="panel-heading collapsed"> | ||
248 | $escapetool.xml($services.localization.render('administration.menu.search.noResults')) | ||
249 | </div> | ||
250 | </div> | ||
251 | </div> | ||
252 | {{/html}} | ||
253 | #end | ||
254 | |||
255 | #macro (verticalNavigationItem $item $options) | ||
256 | #set ($escapedId = $escapetool.xml($item.id)) | ||
257 | #set ($name = "$!item.name") | ||
258 | #if ($name == '') | ||
259 | #set ($name = $services.localization.render("$!options.translationPrefix$item.id")) | ||
260 | #end | ||
261 | #set ($isActive = $item.active == true) | ||
262 | #set ($hasChildren = $item.children && $item.children.size() > 0) | ||
263 | #if ($hasChildren) | ||
264 | #set ($children = []) | ||
265 | #sortCollectionOfMapsByField($item.children, 'order', 99999, 'asc', $children) | ||
266 | <div class="panel panel-default"> | ||
267 | <a class="panel-heading#if (!$isActive) collapsed#end" role="tab" id="panel-heading-$escapedId" | ||
268 | href="$!item.url" data-toggle="collapse"#if ("$!options.id" != '') data-parent="#$options.id" #end | ||
269 | data-target="#panel-body-$escapedId" aria-expanded="$isActive" aria-controls="panel-body-$escapedId" | ||
270 | title="$!escapetool.xml($item.description)">$!services.icon.renderHTML($item.icon)$escapetool.xml($name)</a> | ||
271 | <div class="panel-collapse collapse#if ($isActive) in#end" role="tabpanel" id="panel-body-$escapedId" | ||
272 | aria-labelledby="panel-heading-$escapedId"> | ||
273 | <div class="list-group"> | ||
274 | #foreach ($child in $children) | ||
275 | #verticalNavigationItem($child $options) | ||
276 | #end | ||
277 | </div> | ||
278 | </div> | ||
279 | </div> | ||
280 | #else | ||
281 | <a class="list-group-item#if ($isActive) active#end" data-id="$escapedId" | ||
282 | href="$!item.url" title="$!escapetool.xml($item.description)" | ||
283 | >$!services.icon.renderHTML($item.icon)$escapetool.xml($name)</a> | ||
284 | #end | ||
285 | #end | ||
286 | {{/velocity}} | ||
287 | |||
288 | {{velocity}} | ||
289 | ##************************************************************************************************** | ||
290 | ## Administration Sheet, used to display a common UI for some wiki features (presentation, users, | ||
291 | ## groups, rights etc.) at global / space level and also for several applications. | ||
292 | ##************************************************************************************************** | ||
293 | #if($xcontext.action == 'view' && "$!request.viewer" == '') | ||
294 | $response.sendRedirect($xwiki.getURL($doc.getFullName(), 'admin', $request.getQueryString()))## | ||
295 | #else | ||
296 | $xwiki.jsx.use('XWiki.AdminSheet')## | ||
297 | ## Construct the SSX parameter map. | ||
298 | #set ($parameterMap = {}) | ||
299 | #if ($themeDoc) | ||
300 | #set ($discard = $parameterMap.put('colorTheme', $themeDocFullName)) | ||
301 | #end | ||
302 | $xwiki.ssx.use('XWiki.AdminSheet', $parameterMap)## | ||
303 | #if ("$!crtSectionId" != '' && $crtSectionId.indexOf('.') > 0 && $xwiki.exists($crtSectionId)) | ||
304 | #set ($sectionName = $xwiki.getDocument($crtSectionId).getDisplayTitle()) | ||
305 | #elseif ($crtSectionId != '' && $services.localization.get("admin.${crtSectionId.toLowerCase()}")) | ||
306 | #set ($sectionName = $services.localization.render("admin.${crtSectionId.toLowerCase()}")) | ||
307 | #elseif ("$!crtSectionId" != '') | ||
308 | #set ($sectionName = $crtSectionId) | ||
309 | #elseif ("$!crtCategoryId" != '') | ||
310 | #set ($sectionName = $services.localization.render("admin.$crtCategory.id")) | ||
311 | #elseif ($editor == 'globaladmin') | ||
312 | #set ($sectionName = $services.wiki.getById($xcontext.database).prettyName) | ||
313 | #if ("$!sectionName" == '') | ||
314 | #set ($sectionName = $xcontext.database) | ||
315 | #end | ||
316 | #else | ||
317 | #set ($sectionName = $currentSpace) | ||
318 | #end | ||
319 | |||
320 | {{html}} | ||
321 | #template('hierarchy.vm') | ||
322 | {{/html}} | ||
323 | |||
324 | ## Determine the administration level. | ||
325 | #set ($level = '') | ||
326 | #if ($doc.documentReference.name == 'WebPreferences') | ||
327 | #set ($level = '.page') | ||
328 | #elseif ($doc.fullName == 'XWiki.XWikiPreferences') | ||
329 | #if ($xcontext.isMainWiki()) | ||
330 | #set ($level = '.global') | ||
331 | #else | ||
332 | #set ($level = '.wiki') | ||
333 | #end | ||
334 | #end | ||
335 | (% id="document-title" %)((( | ||
336 | = $services.localization.render("administration.sectionTitle$level", [$sectionName]) = | ||
337 | ## Display the category/section description below the title. | ||
338 | #set ($categoryOrSectionId = $crtCategory.id) | ||
339 | #if ("$!crtSection.id" != '') | ||
340 | #set ($categoryOrSectionId = $crtSection.id) | ||
341 | #end | ||
342 | #set ($descriptionTranslationKey = "admin.$!{categoryOrSectionId.toLowerCase()}.description") | ||
343 | #if ($services.localization.get($descriptionTranslationKey)) | ||
344 | (% class = "noitems" %)((( | ||
345 | $services.localization.render($descriptionTranslationKey) | ||
346 | ))) | ||
347 | #end | ||
348 | |||
349 | ---- | ||
350 | ))) | ||
351 | |||
352 | #verticalNavigation($adminMenu { | ||
353 | 'id': 'administration-menu', | ||
354 | 'translationPrefix': 'admin.', | ||
355 | 'cssClass': 'admin-menu' | ||
356 | }) | ||
357 | |||
358 | ##----------------------------------------- | ||
359 | ## admin-page display | ||
360 | ##----------------------------------------- | ||
361 | #if(!$crtSection && !$crtCategory) | ||
362 | #admin_displayCategories($adminMenu) | ||
363 | #elseif (!$crtSection) | ||
364 | #admin_displayCategory($crtCategory.children) | ||
365 | #else | ||
366 | (% id="admin-page-content" %)((( | ||
367 | ##------------------------------------------------------------------------------------------------------------ | ||
368 | ## The Administration allows editing other pages from different applications inside the admin context (UI) | ||
369 | ##------------------------------------------------------------------------------------------------------------ | ||
370 | #if ($xwiki.exists("XWiki.Admin${section}Sheet")) | ||
371 | ## Handle known XWiki administration sections | ||
372 | {{include reference="XWiki.Admin${section}Sheet" /}} | ||
373 | #elseif ($xwiki.exists($section)) | ||
374 | {{html clean="false"}}#includeForm($section){{/html}} | ||
375 | #end | ||
376 | #if ($crtSection.configurable) | ||
377 | |||
378 | {{include reference="XWiki.ConfigurableClass" /}} | ||
379 | #end | ||
380 | ))) ## admin-page-content | ||
381 | #end | ||
382 | #end | ||
383 | {{/velocity}} |