Исходный код вики User Directory Macros
Версия 3.1 от Андрей Ганьков на 2022/04/05 19:27
Скрыть последних авторов
author | version | line-number | content |
---|---|---|---|
![]() |
1.1 | 1 | {{velocity output='false'}} |
2 | ## Users class | ||
3 | #set ($xwikiUsersClassReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'XWikiUsers')) | ||
4 | #set ($xwikiUsersClass = $xwiki.getDocument($xwikiUsersClassReference).xWikiClass) | ||
5 | ## Configuration class | ||
6 | #set ($directoryPreferencesClassReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryPreferencesClass')) | ||
7 | #set ($directoryPreferencesClassName = $services.model.serialize($directoryPreferencesClassReference)) | ||
8 | ## Default Configuration | ||
9 | #set ($defaultConfigurationDocReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryConfiguration')) | ||
10 | #set ($defaultConfigurationDoc = $xwiki.getDocument($defaultConfigurationDocReference)) | ||
11 | #set ($defaultConfiguration = $defaultConfigurationDoc.getObject($directoryPreferencesClassName)) | ||
12 | |||
13 | ## We use an ordered set to collect the live table columns because we want to avoid duplicates (they break the live | ||
14 | ## table filtering query) and at the same time we want to preserve the column order. | ||
15 | #set ($columns = $collectiontool.orderedSet) | ||
16 | ## Add the fixed columns that we want the user directory to always show. | ||
17 | #set ($discard = $columns.addAll(['_avatar', 'doc.name'])) | ||
18 | |||
19 | ## Default configuration | ||
20 | ## The columns that the user directory will default to when no user preferences exist or when the user resets to default. | ||
21 | ## These defaults can be configured by the wiki's admins. | ||
22 | #set ($isGlobalUserDirectory = $doc.fullName != 'Main.UserDirectory') | ||
23 | #if ($isGlobalUserDirectory) | ||
24 | ## Fallback defaults. | ||
25 | #set ($defaultColumnsString = 'first_name last_name') | ||
26 | #else | ||
27 | ## Admin configured defaults. | ||
28 | #set ($defaultColumnsString = "$!defaultConfiguration.getValue('columns').trim()") | ||
29 | #end | ||
30 | #set ($defaultColumns = $defaultColumnsString.split('\s+')) | ||
31 | |||
32 | ## Current Configuration | ||
33 | #if ($isGlobalUserDirectory || $isGuest || $isSuperAdmin) | ||
34 | ## Use the default configuration when editing the default configuration itself or | ||
35 | ## when the current user doesn't have a profile document, so no preferences. | ||
36 | #set ($configurationDoc = $defaultConfigurationDoc) | ||
37 | #else | ||
38 | ## Use the current user's configuration | ||
39 | #set ($configurationDoc = $xwiki.getDocument($xcontext.userReference)) | ||
40 | #end | ||
41 | ## Get or create the current configuration object, taking into account the values from the request (which is needed for | ||
42 | ## the live preview). | ||
43 | #set ($configuration = $configurationDoc.updateObjectFromRequest($directoryPreferencesClassName)) | ||
44 | |||
45 | ## Read the configuration and initialize with defaults if necessary. | ||
46 | #set ($columnsString = $configuration.getValue('columns').trim()) | ||
47 | #if ($columnsString == $NULL) | ||
48 | #set ($columnsString = $defaultColumnsString) | ||
49 | #set ($discard = $configuration.set('columns', $columnsString)) | ||
50 | #end | ||
51 | |||
52 | ## Check if they are the default preferences. | ||
53 | #set ($isCustomized = false) | ||
54 | #if ($columnsString != $defaultColumnsString) | ||
55 | ## Mark it as a customized user directory. | ||
56 | #set ($isCustomized = true) | ||
57 | #end | ||
58 | |||
59 | ## Build the list of columns to display. | ||
60 | #foreach ($column in $columnsString.split('\s+')) | ||
61 | ## Skip invalid columns. | ||
62 | #if ($column.trim() != '' && $xwikiUsersClass.get($column)) | ||
63 | #set ($discard = $columns.add($column)) | ||
64 | #end | ||
65 | #end | ||
66 | |||
67 | ## | ||
68 | ## Build and display the resulting livetable, nothing else. | ||
69 | ## | ||
70 | #macro (displayUserDirectoryLiveTable) | ||
71 | {{html clean="false"}} | ||
72 | #set ($columnsProperties = {}) | ||
73 | #foreach ($column in $columns) | ||
74 | #set ($columnProperties = { | ||
75 | 'type': 'text', | ||
76 | 'html': false, | ||
77 | 'sortable': true, | ||
78 | 'filterable': true, | ||
79 | 'displayName': $xwikiUsersClass.get($column).translatedPrettyName | ||
80 | }) | ||
81 | #set ($classPropertyType = $xwikiUsersClass.get($column).classType) | ||
82 | #if ($column == '_avatar') | ||
83 | #set ($discard = $columnProperties.putAll({ | ||
84 | 'html': true, | ||
85 | 'sortable': false, | ||
86 | 'filterable': false, | ||
87 | 'link': 'view' | ||
88 | })) | ||
89 | #elseif ($column == 'doc.name') | ||
90 | #set ($columnProperties.link = 'view') | ||
91 | #elseif ($classPropertyType.endsWith('List')) | ||
92 | #set ($columnProperties.type = 'list') | ||
93 | #elseif ($classPropertyType.endsWith('Number')) | ||
94 | #set ($columnProperties.type = 'number') | ||
95 | #elseif ($classPropertyType.endsWith('Password')) | ||
96 | #set ($discard = $columnProperties.putAll({ | ||
97 | 'sortable': false, | ||
98 | 'filterable': false | ||
99 | })) | ||
100 | #elseif ($classPropertyType.endsWith('TextArea') || $classPropertyType.endsWith('Email') || $classPropertyType.endsWith('Groups')) | ||
101 | #set ($columnProperties.html = true) | ||
102 | #end | ||
103 | #set ($discard = $columnsProperties.put($column, $columnProperties)) | ||
104 | #end | ||
105 | ## | ||
106 | ## Allow other applications to provide a different data source for the user directory livetable. For example, some application might define a different membership relation. | ||
107 | #set ($userDirectoryLivetableResultsReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryLivetableResultsOverride')) | ||
108 | #if (!$xwiki.exists($userDirectoryLivetableResultsReference)) | ||
109 | ## If no override is present, use the default data source. | ||
110 | #set ($userDirectoryLivetableResultsReference = $services.model.createDocumentReference($xcontext.database, 'XWiki', 'UserDirectoryLivetableResults')) | ||
111 | #end | ||
112 | ## Note that we specify the class name even though we use a custom results page (which hard-codes it) because the class | ||
113 | ## name is needed by the live table filters, to have a proper drop down list for Static List fields for instance | ||
114 | ## (see XWIKI-9660). | ||
115 | #set ($options = { | ||
116 | 'className': $services.model.serialize($xwikiUsersClassReference, 'local'), | ||
117 | 'resultPage' : "$services.model.serialize($userDirectoryLivetableResultsReference)", | ||
118 | 'translationPrefix' : 'xe.userdirectory.', | ||
119 | 'tagCloud' : true, | ||
120 | 'rowCount': 10, | ||
121 | 'outputOnlyHtml': true | ||
122 | }) | ||
123 | ## Add a filter for subwikis | ||
124 | #if ($xcontext.database != $xcontext.mainWikiName && "$!services.wiki" != '' && "$!services.wiki.user" != '') | ||
125 | #set ($userScope = $services.wiki.user.getUserScope($services.wiki.currentWikiId)) | ||
126 | #if ($userScope == 'GLOBAL_ONLY') | ||
127 | #set ($discard = $options.put('extraParams', 'userScope=global')) | ||
128 | #else | ||
129 | #set ($discard = $options.put('extraParams', 'userScope=local')) | ||
130 | #end | ||
131 | #if ($userScope == 'LOCAL_AND_GLOBAL') | ||
132 | <form class='xform third' action=''> | ||
133 | <dl> | ||
134 | <dt> | ||
135 | <label for='userScopeFilter'>$services.localization.render('userdirectory.userScopeFilter')</label> | ||
136 | <span class='xHint'>$services.localization.render('userdirectory.userScopeFilter.hint')</span> | ||
137 | </dt> | ||
138 | <dd> | ||
139 | <select name='userScope' id='userScopeFilter'> | ||
140 | <option value='local'>$services.localization.render('userdirectory.userScopeFilter.local')</option> | ||
141 | <option value='global'>$services.localization.render('userdirectory.userScopeFilter.global')</option> | ||
142 | </select> | ||
143 | </dd> | ||
144 | </dl> | ||
145 | </form> | ||
146 | #end | ||
147 | #end | ||
148 | ## We can't filter the values of the 'disabled' user profile property directly from the 'extraParams' live table | ||
149 | ## results option because we can't express 'not equal' (we need to say: include only the user profiles for which the | ||
150 | ## value of the 'disabled' property is not equal to 1). An user profile that doesn't have any value set for the | ||
151 | ## 'disabled' property is enabled. | ||
152 | ## We don't hide the disabled user profiles when the active and disabled columns are present because the user can use | ||
153 | ## the live table filters to achieve this. | ||
154 | #set ($hideDisabledProfilesValue = $configuration.getValue('hideDisabledProfiles')) | ||
155 | #if (!$columns.contains('active') | ||
156 | && ($hideDisabledProfilesValue == 1 || ("$!hideDisabledProfilesValue" == '' && | ||
157 | $configuration.xWikiClass.get('hideDisabledProfiles').getValue('defaultValue') == 1))) | ||
158 | #set ($options.extraParams = "$!options.extraParams&hideDisabledProfiles=true") | ||
159 | #end | ||
160 | ## We need to know which users are disabled or inactive in order to display them differently. | ||
161 | #set ($discard = $columns.add('active')) | ||
162 | #set ($discard = $columnsProperties.putIfAbsent('active', {'type': 'hidden'})) | ||
163 | ## Display the computed livetable. | ||
164 | #livetable('userdirectory' $columns $columnsProperties $options) | ||
165 | {{/html}} | ||
166 | #end | ||
167 | |||
168 | ## xredirect value used to come back to the current URL when performing actions | ||
169 | #set ($xredirect = $doc.getURL($xcontext.action, $request.queryString)) | ||
170 | |||
171 | ## | ||
172 | ## Displays the customization form and preview. Also handles the form's actions. | ||
173 | ## | ||
174 | #macro (displayUserDirectoryCustomizationForm) | ||
175 | #if (!$configurationDoc.hasAccessLevel('edit')) | ||
176 | {{error}}$services.localization.render('platform.userdirectory.customizeNotAllowed'){{/error}} | ||
177 | #else | ||
178 | #handleUserDirectoryAction() | ||
179 | ## | ||
180 | ## Customization form | ||
181 | ## | ||
182 | (% id="HUserDirectoryConfiguration" %) | ||
183 | == {{translation key="userdirectory.configuration.title"/}} == | ||
184 | {{html clean="false"}} | ||
185 | <form class="user-directory-settings xform" action="$configurationDoc.getURL('save')" method="post"> | ||
186 | <div class="hidden"> | ||
187 | <input type="hidden" name="form_token" value="$escapetool.xml($services.csrf.token)" /> | ||
188 | <input type="hidden" name="objectPolicy" value="updateOrCreate" /> | ||
189 | <input type="hidden" name="xredirect" value="$escapetool.xml($xredirect)" /> | ||
190 | <input type="hidden" name="comment" value="Updated user directory preferences" /> | ||
191 | </div> | ||
192 | <dl> | ||
193 | #displayProperty('columns' $configuration 'edit') | ||
194 | #displayProperty('hideDisabledProfiles' $configuration 'edit') | ||
195 | </dl> | ||
196 | <p> | ||
197 | <input class="button" type="submit" name="action_save" | ||
198 | value="$escapetool.xml($services.localization.render('xe.userdirectory.customizeSaveButtonLabel'))"/> | ||
199 | #set ($resetQueryString = "$!request.queryString&" + $escapetool.url({ | ||
200 | 'action': 'reset', | ||
201 | 'form_token': $services.csrf.token, | ||
202 | 'xredirect': $xredirect | ||
203 | })) | ||
204 | #set ($resetURL = $doc.getURL($xcontext.action, $resetQueryString)) | ||
205 | <a href="$escapetool.xml($resetURL)" class="button secondary"> | ||
206 | $escapetool.xml($services.localization.render('xe.userdirectory.customizeResetButtonLabel')) | ||
207 | </a> | ||
208 | </p> | ||
209 | </form> | ||
210 | {{/html}} | ||
211 | #end | ||
212 | #end | ||
213 | |||
214 | #macro (handleUserDirectoryAction) | ||
215 | #if ("$!request.action" != '') | ||
216 | #if ($services.csrf.isTokenValid($request.form_token)) | ||
217 | #if ($request.action == 'reset') | ||
218 | #if ($isGlobalUserDirectory) | ||
219 | ## For the global configuration it might be best to keep the object but set default values. | ||
220 | #set ($discard = $configuration.set('columns', $defaultColumnsString)) | ||
221 | #else | ||
222 | ## For user preferences, just remove the object. | ||
223 | #set ($discard = $configurationDoc.removeObject($configuration)) | ||
224 | #end | ||
225 | #set ($discard = $configurationDoc.save('Reset user directory preferences.')) | ||
226 | #end | ||
227 | ## Redirect using xredirect so that the page can be safely refreshed after an action. | ||
228 | #set ($discard = $response.sendRedirect($request.xredirect)) | ||
229 | #elseif ($request.getHeader('X-Requested-With') == 'XMLHttpRequest') | ||
230 | #set ($discard = $response.sendError(401, 'CSRF token verification failed!')) | ||
231 | #else | ||
232 | #set ($discard = $response.sendRedirect($services.csrf.resubmissionURL)) | ||
233 | #end | ||
234 | #stop() | ||
235 | #end | ||
236 | #end | ||
237 | |||
238 | #macro (displayProperty $propertyName $object $action) | ||
239 | #set ($propertyClass = $object.xWikiClass.get($propertyName)) | ||
240 | #set ($isCheckbox = $propertyClass.getValue('displayFormType') == 'checkbox') | ||
241 | #set ($fieldDisplay = $stringtool.removeEnd($stringtool.removeStart($object.display($propertyName, $action), | ||
242 | '{{html clean="false" wiki="false"}}'), '{{/html}}')) | ||
243 | <dt> | ||
244 | <label #if ($action == 'edit' && !$isCheckbox) | ||
245 | for="$escapetool.xml("${object.xWikiClass.name}_${object.number}_$propertyName")"#end> | ||
246 | #if ($isCheckbox) | ||
247 | $fieldDisplay | ||
248 | #end | ||
249 | $escapetool.xml($propertyClass.translatedPrettyName) | ||
250 | </label> | ||
251 | <span class="xHint"> | ||
252 | $!escapetool.xml($propertyClass.hint) | ||
253 | </span> | ||
254 | </dt> | ||
255 | <dd>#if (!$isCheckbox)$fieldDisplay#end</dd> | ||
256 | #end | ||
257 | |||
258 | ## | ||
259 | ## Displays the user directory with customization status and customization form for when it is being customized. | ||
260 | ## | ||
261 | #macro (displayUserDirectoryCustomizationOptions $customize) | ||
262 | ## | ||
263 | ## Ability to customize the view. | ||
264 | ## | ||
265 | #if ($customize) | ||
266 | #displayUserDirectoryCustomizationForm() | ||
267 | #elseif ($isCustomized) | ||
268 | {{warning}} | ||
269 | $services.localization.render('xe.userdirectory.isCustomizedWarning', [ | ||
270 | "$doc.fullName", | ||
271 | $escapetool.url({ | ||
272 | 'customize': true, | ||
273 | 'action': 'reset', | ||
![]() |
3.1 | 274 | 'xredirect': $xredirect, |
275 | 'form_token': $services.csrf.token | ||
![]() |
1.1 | 276 | }), |
277 | "$doc.fullName", | ||
278 | 'customize=true' | ||
279 | ]) | ||
280 | {{/warning}} | ||
281 | #elseif ($isGuest) | ||
282 | {{info}} | ||
283 | $services.localization.render('xe.userdirectory.canCustomizeInfoGuest', ["path:$doc.getURL('login')"]) | ||
284 | {{/info}} | ||
285 | #else | ||
286 | {{info}} | ||
287 | $services.localization.render('xe.userdirectory.canCustomizeInfo', ["$doc.fullName", 'customize=true']) | ||
288 | {{/info}} | ||
289 | #end | ||
290 | #end | ||
291 | |||
292 | ## | ||
293 | ## Displays the user directory. | ||
294 | ## | ||
295 | #macro (displayUserDirectory $customize) | ||
296 | #set ($discard = $xwiki.jsx.use('XWiki.UserDirectoryMacros')) | ||
297 | #displayUserDirectoryCustomizationOptions($customize) | ||
298 | |||
299 | #if ($customize) | ||
300 | (% id="HUserDirectoryCustomizePreview" %) | ||
301 | == {{translation key="xe.userdirectory.customizePreviewTitle"/}} == | ||
302 | |||
303 | #end | ||
304 | #displayUserDirectoryLiveTable() | ||
305 | #end | ||
306 | {{/velocity}} |