Code source wiki de MacroService

Version 4.1 par Xavier Richard le 01/04/2019 à 19:31

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 ($translatedParameterDescriptor.editTemplate = $services.display.html.display(
162 $translatedParameterDescriptor.type, $translatedParameterDescriptor.defaultValue,
163 {'name': $parameterDescriptor.id}, 'edit'))
164 #if ("$!translatedParameterDescriptor.editTemplate" == '')
165 #set ($translatedParameterDescriptor.editTemplate = "#getMacroParameterEditTemplate(
166 $translatedParameterDescriptor)")
167 #end
168 #set ($translatedParameterDescriptor.editTemplate = $translatedParameterDescriptor.editTemplate.trim())
169 #fixDescriptorType($translatedParameterDescriptor)
170 ## Make sure the key is lowercase (for XWiki <9.0).
171 ## See XWIKI-13990: Inconsistency between Java-based and Wiki-based rendering macros regarding the parameter
172 ## descriptor map keys
173 #set ($discard = $data.parameterDescriptorMap.put($entry.key.toLowerCase(), $translatedParameterDescriptor))
174 #end
175 #if ($groupDescriptorTree.groups)
176 #set ($data.groupDescriptorTree = $groupDescriptorTree.groups)
177 #end
178 #set ($data.requiredSkinExtensions = "#getRequiredSkinExtensions")
179 #end
180
181 #macro (fixDescriptorType $descriptor)
182 ## The goal of this code is to obtain a normalized string representation of the type specified in the descriptor.
183 ## See XCOMMONS-1583: Define a stable way to serialize types
184 ##
185 ## The type specified in the descriptor can be any implementation of java.lang.reflect.Type, not necessarily a
186 ## java.lang.Class. We can't use toString() because the return of Class#toString() is different than Class#getName().
187 ## We can't use Type#getTypeName() either because the access to this method is restricted from Velocity. The only
188 ## option for now is to try #getName() first and fall back on #toString() for types that are not instances of
189 ## java.lang.Class.
190 #set ($typeName = $descriptor.type.getName())
191 #if ("$!typeName" == '')
192 ## Probably not a java.lang.Class. Fall back on #toString().
193 #set ($typeName = "$!descriptor.type")
194 #end
195 ## Remove whitespace from the type name in order to have a single string representation.
196 #set ($descriptor.type = $typeName.replaceAll('\s+', ''))
197 #end
198
199 ## Builds the group tree with the following structure:
200 ##
201 ## {
202 ## 'parentGroupId': {
203 ## 'id': 'parentGroupId',
204 ## 'name': 'Parent Group',
205 ## 'feature': 'someFeature',
206 ## 'groups': {
207 ## 'childGroupId': {...},
208 ## ...
209 ## }
210 ## },
211 ## ...
212 ## }
213 #macro (handleMacroParameterGroup $groupDescriptor $groupDescriptorTree $translatedParameterDescriptor)
214 #if ($groupDescriptor.group && $groupDescriptor.group.size() > 0)
215 #set ($translatedParameterDescriptor.group = $groupDescriptor.group)
216 #set ($parentGroup = $groupDescriptorTree)
217 #foreach ($groupId in $groupDescriptor.group)
218 #if (!$parentGroup.groups)
219 #set ($parentGroup.groups = {})
220 #end
221 #set ($childGroup = $parentGroup.groups.get($groupId))
222 #if (!$childGroup)
223 #if ($groupId == $translatedParameterDescriptor.id)
224 #set ($groupName = $translatedParameterDescriptor.name)
225 #else
226 #set ($groupTranslationKey = "${macroTranslationKey}.group.$groupId")
227 #set ($groupName = "#maybeTranslate(""${groupTranslationKey}.name"" $groupId)")
228 #end
229 #set ($childGroup = {
230 'id': $groupId,
231 'name': $groupName
232 })
233 #set ($discard = $parentGroup.groups.put($groupId, $childGroup))
234 #end
235 #set ($parentGroup = $childGroup)
236 #end
237 #if ("$!groupDescriptor.feature" != '')
238 #set ($parentGroup.feature = $groupDescriptor.feature)
239 #end
240 #elseif ($groupDescriptor.feature)
241 ## This group is made of a single parameter. The feature then refers to this parameter.
242 #set ($translatedParameterDescriptor.feature = $groupDescriptor.feature)
243 #end
244 #end
245
246 #macro (initRequiredSkinExtensions)
247 #set ($requiredSkinExtensions = $collectionstool.orderedMap)
248 ## Save the import string for each skin extension plugin in order to be able to remove the always used extensions
249 ## (they are aready available on the edit page so there's no need to load them).
250 #foreach ($pluginName in ['ssrx', 'ssfx', 'ssx', 'linkx', 'jsrx', 'jsfx', 'jsx'])
251 #set ($discard = $requiredSkinExtensions.put($pluginName, $xwiki.get($pluginName).importString))
252 #end
253 #end
254
255 #macro (getRequiredSkinExtensions)
256 #foreach ($entry in $requiredSkinExtensions.entrySet())
257 #set ($importString = $xwiki.get($entry.key).importString)
258 ## Remove the always used skin extensions, keep only those that have been requested by the macro parameter pickers.
259 $!stringtool.removeStart($importString, $entry.value).trim()##
260 #end
261 #end
262
263 #macro (getMacroParameterEditTemplate $translatedParameterDescriptor)
264 #if ($translatedParameterDescriptor.type.getName() == 'boolean'
265 || $translatedParameterDescriptor.type.getName() == 'java.lang.Boolean')
266 <input type="checkbox" name="$escapetool.xml($translatedParameterDescriptor.id)" value="true"/>##
267 ## We need to submit something in case the checkbox is not checked.
268 <input type="hidden" name="$escapetool.xml($translatedParameterDescriptor.id)" value="false"/>
269 #elseif ($translatedParameterDescriptor.type.isEnum())
270 #if ($translatedParameterDescriptor.defaultValue)
271 #set ($parameterValues = $translatedParameterDescriptor.defaultValue.values())
272 #else
273 ## A parameter of type enum that doesn't have a default value is very unlikely. We attempt to read the list of
274 ## possible values from the enum type in this case, which is currently forbidden, but at least it will generate
275 ## a warning in the logs that will help us investigate the problem.
276 #set ($parameterValues = $translatedParameterDescriptor.type.getEnumConstants())
277 #end
278 <select name="$escapetool.xml($translatedParameterDescriptor.id)">##
279 #foreach ($parameterValue in $parameterValues)
280 #set ($label = "#maybeTranslate(""${parameterTranslationKey}.value.$parameterValue"" $parameterValue)")
281 <option value="$escapetool.xml($parameterValue)">$escapetool.xml($label)</option>##
282 #end
283 </select>
284 #else
285 <input type="text" name="$escapetool.xml($translatedParameterDescriptor.id)"/>
286 #end
287 #end
288
289 #macro (maybeTranslate $key $defaultValue)
290 #if ($services.localization.get($key))
291 $services.localization.render($key)##
292 #else
293 $!defaultValue##
294 #end
295 #end
296 {{/velocity}}
297
298 {{velocity wiki="false"}}
299 #if ("$!request.data" != '')
300 #set ($data = $NULL)
301 #if ($request.data == 'list')
302 #getMacroList($request.syntaxId)
303 #elseif ($request.data == 'descriptor')
304 #maybeGetMacroDescriptor($request.macroId)
305 #end
306 #if ($data)
307 #set ($discard = $response.setContentType('application/json'))
308 $jsontool.serialize($data)
309 #else
310 $response.sendError(404)
311 #end
312 #end
313 {{/velocity}}