Code source wiki de MacroService

Version 5.1 par Xavier Richard le 20/08/2019 à 09:56

Afficher les derniers auteurs
1 {{velocity output="false"}}
2 ## ================================================================
3 ## Returned JSON format:
4 ##
5 ## {
6 ## 'options': {
7 ## 'allMacrosExcludedCategories': [
8 ## (translated category name), ...
9 ## ]
10 ## },
11 ## 'list': [
12 ## {
13 ## 'id': (macro id),
14 ## 'name': (translated macro name),
15 ## 'description': (translated macro description),
16 ## 'defaultCategory': (translated macro category),
17 ## },
18 ## ...
19 ## ]
20 ## }
21 ## ================================================================
22 #macro (getMacroList $syntaxId)
23 #set ($syntax = $services.rendering.resolveSyntax($syntaxId))
24 #set ($macroDescriptors = $services.rendering.getMacroDescriptors($syntax))
25 #if (!$macroDescriptors)
26 ## Before XWiki 9.7RC1 we had to use APIs that require programming rights.
27 #set ($macroDescriptors = [])
28 #try()
29 #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager'))
30 #foreach ($macroId in $macroManager.getMacroIds($syntax))
31 #set ($macroDescriptor = $macroManager.getMacro($macroId).descriptor)
32 #set ($discard = $macroDescriptors.add($macroDescriptor))
33 #end
34 #end
35 #end
36 #set ($data = {})
37 #set ($allMacrosExcludedCategories = [])
38 #set ($discard = $allMacrosExcludedCategories.add("#maybeTranslate('rendering.macroCategory.Internal' 'Internal')"))
39 #set ($discard = $allMacrosExcludedCategories.add("#maybeTranslate('rendering.macroCategory.Deprecated' 'Deprecated')"))
40 #set ($discard = $data.put('options', { 'allMacrosExcludedCategories' : $allMacrosExcludedCategories }))
41 #set ($macroList = [])
42 #foreach ($macroDescriptor in $macroDescriptors)
43 #set ($macroTranslationKey = "rendering.macro.$macroDescriptor.id")
44 #set ($macroCategoryTranslationKey = "rendering.macroCategory.$macroDescriptor.defaultCategory")
45 #set ($discard = $macroList.add({
46 'id': $macroDescriptor.id,
47 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)",
48 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)",
49 'defaultCategory': "#maybeTranslate($macroCategoryTranslationKey $macroDescriptor.defaultCategory)"
50 }))
51 #end
52 #set ($macroList = $sorttool.sort($macroList, 'name'))
53 #set ($discard = $data.put('list', $macroList))
54 #end
55
56 #macro (maybeGetMacroDescriptor $macroIdAsString)
57 #set ($xmacro = $NULL)
58 #set ($macroDescriptor = $NULL)
59 #set ($macroId = $services.rendering.resolveMacroId($macroIdAsString))
60 #if ($macroId)
61 #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId))
62 #if (!$macroDescriptor && $macroId.syntax)
63 ## Try the macro id without the syntax.
64 #set ($macroId = $services.rendering.resolveMacroId($macroId.id))
65 #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId))
66 #end
67 #else
68 ## Either the macro id could not be resolved (unlikely) or we are on an older XWiki instance (before 10.10RC1) where
69 ## we had to use APIs that require programming rights.
70 #getMacroWithPR($macroIdAsString)
71 #if ($xmacro)
72 #set ($macroDescriptor = $xmacro.descriptor)
73 #end
74 #end
75 #if ($macroDescriptor)
76 #getMacroDescriptor($macroDescriptor)
77 #if ($xmacro)
78 ## supportsInlineMode was not exposed on the macro descriptor before XWiki 10.10RC1.
79 #set ($data.supportsInlineMode = $xmacro.supportsInlineMode())
80 #end
81 #end
82 #end
83
84 #macro (getMacroWithPR $macroIdAsString)
85 #set ($xmacro = $NULL)
86 #try()
87 #set ($macroIdFactory = $services.component.getInstance('org.xwiki.rendering.macro.MacroIdFactory'))
88 #set ($macroId = $macroIdFactory.createMacroId($macroIdAsString))
89 #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager'))
90 #if ($macroManager.exists($macroId))
91 #set ($xmacro = $macroManager.getMacro($macroId))
92 #elseif ($macroId.syntax)
93 ## Try the macro id without the syntax.
94 #set ($macroId = $macroIdFactory.createMacroId($macroId.id))
95 #if ($macroManager.exists($macroId))
96 #set ($xmacro = $macroManager.getMacro($macroId))
97 #end
98 #end
99 #end
100 #end
101
102 #macro (getMacroDescriptor $macroDescriptor)
103 ## Translate the macro name and description.
104 #set ($macroTranslationKey = "rendering.macro.$macroDescriptor.id")
105 #initRequiredSkinExtensions
106 #set ($data = {
107 'id': $macroDescriptor.id,
108 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)",
109 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)",
110 'defaultCategory': $macroDescriptor.defaultCategory,
111 'supportsInlineMode': $macroDescriptor.supportsInlineMode(),
112 'parameterDescriptorMap': {}
113 })
114 #if ($macroDescriptor.contentDescriptor)
115 ## Translate the content label and description.
116 ## Treat the macro content as if it is the last macro parameter.
117 #set ($data.contentDescriptor = {
118 'name': "#maybeTranslate('rendering.macroContent' 'Content')",
119 'description': "#maybeTranslate(""${macroTranslationKey}.content.description""
120 $macroDescriptor.contentDescriptor.description)",
121 'mandatory': $macroDescriptor.contentDescriptor.mandatory,
122 'deprecated': $macroDescriptor.contentDescriptor.deprecated,
123 'advanced': $macroDescriptor.contentDescriptor.advanced,
124 'defaultValue': $macroDescriptor.contentDescriptor.defaultValue,
125 'type': $macroDescriptor.contentDescriptor.type,
126 'editTemplate': '<textarea name="$content" rows="7"></textarea>',
127 'index': $macroDescriptor.parameterDescriptorMap.size()
128 })
129 #fixDescriptorType($data.contentDescriptor)
130 #end
131 #set ($groupDescriptorTree = {})
132 #foreach ($entry in $macroDescriptor.parameterDescriptorMap.entrySet())
133 #set ($parameterDescriptor = $entry.value)
134 ## Translate the parameter name and description.
135 #set ($parameterTranslationKey = "${macroTranslationKey}.parameter.$parameterDescriptor.id")
136 #set ($translatedParameterDescriptor = {
137 'id': $parameterDescriptor.id,
138 'name': "#maybeTranslate(""${parameterTranslationKey}.name"" $parameterDescriptor.name)",
139 'description': "#maybeTranslate(""${parameterTranslationKey}.description"" $parameterDescriptor.description)",
140 'mandatory': $parameterDescriptor.mandatory,
141 'deprecated': $parameterDescriptor.deprecated,
142 'advanced': $parameterDescriptor.advanced,
143 'defaultValue': $parameterDescriptor.defaultValue,
144 'type': $parameterDescriptor.displayType,
145 'index': $foreach.index
146 })
147 #if ("$!translatedParameterDescriptor.type" == '')
148 ## displayType is not available before XWiki 11.0 so we need to fall back on parameterType.
149 #set ($translatedParameterDescriptor.type = $parameterDescriptor.parameterType)
150 #end
151 #set ($groupDescriptor = $parameterDescriptor.groupDescriptor)
152 #if ($groupDescriptor)
153 #handleMacroParameterGroup($groupDescriptor $groupDescriptorTree $translatedParameterDescriptor)
154 #end
155 #if ($translatedParameterDescriptor.type.getName() == 'java.lang.String'
156 && ($parameterDescriptor.defaultValue == 'false' || $parameterDescriptor.defaultValue == 'true')
157 && $macroDescriptor.parametersBeanClass.getSimpleName() == 'WikiMacroParameters')
158 #set ($translatedParameterDescriptor.defaultValue = $parameterDescriptor.defaultValue == 'true')
159 #set ($translatedParameterDescriptor.type = $translatedParameterDescriptor.defaultValue.getClass())
160 #end
161 #set ($htmlDisplayerParameters = {'name': $parameterDescriptor.id})
162 #if ($translatedParameterDescriptor.group)
163 #set ($discard = $htmlDisplayerParameters.put('data-property-group',
164 $stringtool.join($translatedParameterDescriptor.group, '/')))
165 #end
166 #set ($translatedParameterDescriptor.editTemplate = $services.display.html.display(
167 $translatedParameterDescriptor.type, $translatedParameterDescriptor.defaultValue, $htmlDisplayerParameters, 'edit'
168 ))
169 #if ("$!translatedParameterDescriptor.editTemplate" == '')
170 #set ($translatedParameterDescriptor.editTemplate = "#getMacroParameterEditTemplate(
171 $translatedParameterDescriptor)")
172 #end
173 #set ($translatedParameterDescriptor.editTemplate = $translatedParameterDescriptor.editTemplate.trim())
174 #fixDescriptorType($translatedParameterDescriptor)
175 ## Make sure the key is lowercase (for XWiki <9.0).
176 ## See XWIKI-13990: Inconsistency between Java-based and Wiki-based rendering macros regarding the parameter
177 ## descriptor map keys
178 #set ($discard = $data.parameterDescriptorMap.put($entry.key.toLowerCase(), $translatedParameterDescriptor))
179 #end
180 #if ($groupDescriptorTree.groups)
181 #set ($data.groupDescriptorTree = $groupDescriptorTree.groups)
182 #end
183 #set ($data.requiredSkinExtensions = "#getRequiredSkinExtensions")
184 #end
185
186 #macro (fixDescriptorType $descriptor)
187 ## The goal of this code is to obtain a normalized string representation of the type specified in the descriptor.
188 ## See XCOMMONS-1583: Define a stable way to serialize types
189 ##
190 ## The type specified in the descriptor can be any implementation of java.lang.reflect.Type, not necessarily a
191 ## java.lang.Class. We can't use toString() because the return of Class#toString() is different than Class#getName().
192 ## We can't use Type#getTypeName() either because the access to this method is restricted from Velocity. The only
193 ## option for now is to try #getName() first and fall back on #toString() for types that are not instances of
194 ## java.lang.Class.
195 #set ($typeName = $descriptor.type.getName())
196 #if ("$!typeName" == '')
197 ## Probably not a java.lang.Class. Fall back on #toString().
198 #set ($typeName = "$!descriptor.type")
199 #end
200 ## Remove whitespace from the type name in order to have a single string representation.
201 #set ($descriptor.type = $typeName.replaceAll('\s+', ''))
202 #end
203
204 ## Builds the group tree with the following structure:
205 ##
206 ## {
207 ## 'parentGroupId': {
208 ## 'id': 'parentGroupId',
209 ## 'name': 'Parent Group',
210 ## 'feature': 'someFeature',
211 ## 'groups': {
212 ## 'childGroupId': {...},
213 ## ...
214 ## }
215 ## },
216 ## ...
217 ## }
218 #macro (handleMacroParameterGroup $groupDescriptor $groupDescriptorTree $translatedParameterDescriptor)
219 #if ($groupDescriptor.group && $groupDescriptor.group.size() > 0)
220 #set ($translatedParameterDescriptor.group = $groupDescriptor.group)
221 #set ($parentGroup = $groupDescriptorTree)
222 #foreach ($groupId in $groupDescriptor.group)
223 #if (!$parentGroup.groups)
224 #set ($parentGroup.groups = {})
225 #end
226 #set ($childGroup = $parentGroup.groups.get($groupId))
227 #if (!$childGroup)
228 #if ($groupId == $translatedParameterDescriptor.id)
229 #set ($groupName = $translatedParameterDescriptor.name)
230 #else
231 #set ($groupTranslationKey = "${macroTranslationKey}.group.$groupId")
232 #set ($groupName = "#maybeTranslate(""${groupTranslationKey}.name"" $groupId)")
233 #end
234 #set ($childGroup = {
235 'id': $groupId,
236 'name': $groupName
237 })
238 #set ($discard = $parentGroup.groups.put($groupId, $childGroup))
239 #end
240 #set ($parentGroup = $childGroup)
241 #end
242 #if ("$!groupDescriptor.feature" != '')
243 #set ($parentGroup.feature = $groupDescriptor.feature)
244 #end
245 #elseif ($groupDescriptor.feature)
246 ## This group is made of a single parameter. The feature then refers to this parameter.
247 #set ($translatedParameterDescriptor.feature = $groupDescriptor.feature)
248 #end
249 #end
250
251 #macro (initRequiredSkinExtensions)
252 #set ($requiredSkinExtensions = $collectionstool.orderedMap)
253 ## Save the import string for each skin extension plugin in order to be able to remove the always used extensions
254 ## (they are aready available on the edit page so there's no need to load them).
255 #foreach ($pluginName in ['ssrx', 'ssfx', 'ssx', 'linkx', 'jsrx', 'jsfx', 'jsx'])
256 #set ($discard = $requiredSkinExtensions.put($pluginName, $xwiki.get($pluginName).importString))
257 #end
258 #end
259
260 #macro (getRequiredSkinExtensions)
261 #foreach ($entry in $requiredSkinExtensions.entrySet())
262 #set ($importString = $xwiki.get($entry.key).importString)
263 ## Remove the always used skin extensions, keep only those that have been requested by the macro parameter pickers.
264 $!stringtool.removeStart($importString, $entry.value).trim()##
265 #end
266 #end
267
268 #macro (getMacroParameterEditTemplate $translatedParameterDescriptor)
269 #if ($translatedParameterDescriptor.type.getName() == 'boolean'
270 || $translatedParameterDescriptor.type.getName() == 'java.lang.Boolean')
271 <input type="checkbox" name="$escapetool.xml($translatedParameterDescriptor.id)" value="true"/>##
272 ## We need to submit something in case the checkbox is not checked.
273 <input type="hidden" name="$escapetool.xml($translatedParameterDescriptor.id)" value="false"/>
274 #elseif ($translatedParameterDescriptor.type.isEnum())
275 #if ($translatedParameterDescriptor.defaultValue)
276 #set ($parameterValues = $translatedParameterDescriptor.defaultValue.values())
277 #else
278 ## A parameter of type enum that doesn't have a default value is very unlikely. We attempt to read the list of
279 ## possible values from the enum type in this case, which is currently forbidden, but at least it will generate
280 ## a warning in the logs that will help us investigate the problem.
281 #set ($parameterValues = $translatedParameterDescriptor.type.getEnumConstants())
282 #end
283 <select name="$escapetool.xml($translatedParameterDescriptor.id)">##
284 #foreach ($parameterValue in $parameterValues)
285 #set ($label = "#maybeTranslate(""${parameterTranslationKey}.value.$parameterValue"" $parameterValue)")
286 <option value="$escapetool.xml($parameterValue)">$escapetool.xml($label)</option>##
287 #end
288 </select>
289 #else
290 <input type="text" name="$escapetool.xml($translatedParameterDescriptor.id)"/>
291 #end
292 #end
293
294 #macro (maybeTranslate $key $defaultValue)
295 #if ($services.localization.get($key))
296 $services.localization.render($key)##
297 #else
298 $!defaultValue##
299 #end
300 #end
301 {{/velocity}}
302
303 {{velocity wiki="false"}}
304 #if ("$!request.data" != '')
305 #set ($data = $NULL)
306 #if ($request.data == 'list')
307 #getMacroList($request.syntaxId)
308 #elseif ($request.data == 'descriptor')
309 #maybeGetMacroDescriptor($request.macroId)
310 #end
311 #if ($data)
312 #set ($discard = $response.setContentType('application/json'))
313 $jsontool.serialize($data)
314 #else
315 $response.sendError(404)
316 #end
317 #end
318 {{/velocity}}