Modifications pour le document MacroService

Modifié par Florent Charton le 2026/03/13 11:04

Depuis la version 5.1
modifié par Florent Charton
sur 2026/01/13 15:01
Commentaire de modification : Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/17.10.2]
À la version 3.1
modifié par Florent Charton
sur 2024/08/08 18:44
Commentaire de modification : Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/15.10.11]

Résumé

Détails

Propriétés de la Page
Contenu
... ... @@ -57,6 +57,17 @@
57 57  
58 58   #set ($syntax = $services.rendering.resolveSyntax($syntaxId))
59 59   #set ($macroDescriptors = $services.rendering.getMacroDescriptors($syntax))
60 + #if (!$macroDescriptors)
61 + ## Before XWiki 9.7RC1 we had to use APIs that require programming rights.
62 + #set ($macroDescriptors = [])
63 + #try()
64 + #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager'))
65 + #foreach ($macroId in $macroManager.getMacroIds($syntax))
66 + #set ($macroDescriptor = $macroManager.getMacro($macroId).descriptor)
67 + #set ($discard = $macroDescriptors.add($macroDescriptor))
68 + #end
69 + #end
70 + #end
60 60   #set ($data = {})
61 61   #set ($allMacrosExcludedCategories = [])
62 62   #set ($discard = $allMacrosExcludedCategories.add("#maybeTranslate('rendering.macroCategory.Internal' 'Internal')"))
... ... @@ -98,7 +98,7 @@
98 98   }))
99 99   #end
100 100   #end
101 - #set ($macroList = $collectiontool.sort($macroList, 'name'))
112 + #set ($macroList = $resolvedSortTool.sort($macroList, 'name'))
102 102   #set ($discard = $data.put('list', $macroList))
103 103   ## Get macros provided by compatible available extensions
104 104   #set ($macroExtensionsList = [])
... ... @@ -150,16 +150,236 @@
150 150  #end
151 151  
152 152  #macro (maybeGetMacroDescriptor $macroIdAsString)
153 - #ckeditor_initRequiredSkinExtensions()
154 - #set ($macroDescriptor = $services.wysiwyg.getMacroDescriptorUI($macroIdAsString))
164 + #set ($xmacro = $NULL)
165 + #set ($macroDescriptor = $NULL)
166 + #set ($macroId = $services.rendering.resolveMacroId($macroIdAsString))
167 + #if ($macroId)
168 + #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId))
169 + #if (!$macroDescriptor && $macroId.syntax)
170 + ## Try the macro id without the syntax.
171 + #set ($macroId = $services.rendering.resolveMacroId($macroId.id))
172 + #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId))
173 + #end
174 + #else
175 + ## Either the macro id could not be resolved (unlikely) or we are on an older XWiki instance (before 10.10RC1) where
176 + ## we had to use APIs that require programming rights.
177 + #getMacroWithPR($macroIdAsString)
178 + #if ($xmacro)
179 + #set ($macroDescriptor = $xmacro.descriptor)
180 + #end
181 + #end
155 155   #if ($macroDescriptor)
156 - #set ($data = {
157 - 'descriptor': $macroDescriptor,
158 - 'requiredSkinExtensions': "#ckeditor_getRequiredSkinExtensions()"
183 + #getMacroDescriptor($macroDescriptor)
184 + #if ($xmacro)
185 + ## supportsInlineMode was not exposed on the macro descriptor before XWiki 10.10RC1.
186 + #set ($data.supportsInlineMode = $xmacro.supportsInlineMode())
187 + #end
188 + #end
189 +#end
190 +
191 +#macro (getMacroWithPR $macroIdAsString)
192 + #set ($xmacro = $NULL)
193 + #try()
194 + #set ($macroIdFactory = $services.component.getInstance('org.xwiki.rendering.macro.MacroIdFactory'))
195 + #set ($macroId = $macroIdFactory.createMacroId($macroIdAsString))
196 + #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager'))
197 + #if ($macroManager.exists($macroId))
198 + #set ($xmacro = $macroManager.getMacro($macroId))
199 + #elseif ($macroId.syntax)
200 + ## Try the macro id without the syntax.
201 + #set ($macroId = $macroIdFactory.createMacroId($macroId.id))
202 + #if ($macroManager.exists($macroId))
203 + #set ($xmacro = $macroManager.getMacro($macroId))
204 + #end
205 + #end
206 + #end
207 +#end
208 +
209 +#macro (getMacroDescriptor $macroDescriptor)
210 + ## Translate the macro name and description.
211 + #set ($macroTranslationKey = "rendering.macro.$macroDescriptor.id")
212 + #ckeditor_initRequiredSkinExtensions()
213 + #set ($data = {
214 + 'id': $macroDescriptor.id,
215 + 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)",
216 + 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)",
217 + 'defaultCategory': $macroDescriptor.defaultCategory,
218 + 'supportsInlineMode': $macroDescriptor.supportsInlineMode(),
219 + 'parameterDescriptorMap': {}
220 + })
221 + #if ($macroDescriptor.contentDescriptor)
222 + ## Translate the content label and description.
223 + ## Treat the macro content as if it is the last macro parameter.
224 + #set ($data.contentDescriptor = {
225 + 'name': "#maybeTranslate('rendering.macroContent' 'Content')",
226 + 'description': "#maybeTranslate(""${macroTranslationKey}.content.description""
227 + $macroDescriptor.contentDescriptor.description)",
228 + 'mandatory': $macroDescriptor.contentDescriptor.mandatory,
229 + 'deprecated': $macroDescriptor.contentDescriptor.deprecated,
230 + 'advanced': $macroDescriptor.contentDescriptor.advanced,
231 + 'defaultValue': $macroDescriptor.contentDescriptor.defaultValue,
232 + 'type': $macroDescriptor.contentDescriptor.type,
233 + 'editTemplate': '<textarea name="$content" rows="7"></textarea>',
234 + 'index': $macroDescriptor.parameterDescriptorMap.size()
159 159   })
236 + #fixDescriptorType($data.contentDescriptor)
160 160   #end
238 + #set ($groupDescriptorTree = {})
239 + #foreach ($entry in $macroDescriptor.parameterDescriptorMap.entrySet())
240 + #set ($parameterDescriptor = $entry.value)
241 + ## Translate the parameter name and description.
242 + #set ($parameterTranslationKey = "${macroTranslationKey}.parameter.$parameterDescriptor.id")
243 + ## Note: The displayHidden parameter is new in XWiki 12.4RC1 so make sure we set 'hidden' to false if it doesn't
244 + ## exist
245 + #if ("$!parameterDescriptor.displayHidden" != '')
246 + #set ($parameterHidden = $parameterDescriptor.displayHidden)
247 + #else
248 + #set ($parameterHidden = false)
249 + #end
250 + #set ($translatedParameterDescriptor = {
251 + 'id': $parameterDescriptor.id,
252 + 'name': "#maybeTranslate(""${parameterTranslationKey}.name"" $parameterDescriptor.name)",
253 + 'description': "#maybeTranslate(""${parameterTranslationKey}.description"" $parameterDescriptor.description)",
254 + 'mandatory': $parameterDescriptor.mandatory,
255 + 'deprecated': $parameterDescriptor.deprecated,
256 + 'advanced': $parameterDescriptor.advanced,
257 + 'defaultValue': $parameterDescriptor.defaultValue,
258 + 'type': $parameterDescriptor.displayType,
259 + 'hidden' : $parameterHidden,
260 + 'index': $foreach.index
261 + })
262 + #if ("$!translatedParameterDescriptor.type" == '')
263 + ## displayType is not available before XWiki 11.0 so we need to fall back on parameterType.
264 + #set ($translatedParameterDescriptor.type = $parameterDescriptor.parameterType)
265 + #end
266 + #set ($translatedParameterDescriptor.caseInsensitive = $translatedParameterDescriptor.type.isEnum())
267 + #set ($groupDescriptor = $parameterDescriptor.groupDescriptor)
268 + #if ($groupDescriptor)
269 + #handleMacroParameterGroup($groupDescriptor $groupDescriptorTree $translatedParameterDescriptor)
270 + #end
271 + #if ($translatedParameterDescriptor.type.getName() == 'java.lang.String'
272 + && ($parameterDescriptor.defaultValue == 'false' || $parameterDescriptor.defaultValue == 'true')
273 + && $macroDescriptor.parametersBeanClass.getSimpleName() == 'WikiMacroParameters')
274 + #set ($translatedParameterDescriptor.defaultValue = $parameterDescriptor.defaultValue == 'true')
275 + #set ($translatedParameterDescriptor.type = $translatedParameterDescriptor.defaultValue.getClass())
276 + #end
277 + #set ($htmlDisplayerParameters = {'name': $parameterDescriptor.id})
278 + #if ($translatedParameterDescriptor.group)
279 + #set ($discard = $htmlDisplayerParameters.put('data-property-group',
280 + $stringtool.join($translatedParameterDescriptor.group, '/')))
281 + #end
282 + #set ($translatedParameterDescriptor.editTemplate = $services.display.html.display(
283 + $translatedParameterDescriptor.type, $translatedParameterDescriptor.defaultValue, $htmlDisplayerParameters, 'edit'
284 + ))
285 + #if ("$!translatedParameterDescriptor.editTemplate" == '')
286 + #set ($translatedParameterDescriptor.editTemplate = "#getMacroParameterEditTemplate(
287 + $translatedParameterDescriptor)")
288 + #end
289 + #set ($translatedParameterDescriptor.editTemplate = $translatedParameterDescriptor.editTemplate.trim())
290 + #fixDescriptorType($translatedParameterDescriptor)
291 + ## Make sure the key is lowercase (for XWiki <9.0).
292 + ## See XWIKI-13990: Inconsistency between Java-based and Wiki-based rendering macros regarding the parameter
293 + ## descriptor map keys
294 + #set ($discard = $data.parameterDescriptorMap.put($entry.key.toLowerCase(), $translatedParameterDescriptor))
295 + #end
296 + #if ($groupDescriptorTree.groups)
297 + #set ($data.groupDescriptorTree = $groupDescriptorTree.groups)
298 + #end
299 + #set ($data.requiredSkinExtensions = "#ckeditor_getRequiredSkinExtensions()")
161 161  #end
162 162  
302 +#macro (fixDescriptorType $descriptor)
303 + ## The goal of this code is to obtain a normalized string representation of the type specified in the descriptor.
304 + ## See XCOMMONS-1583: Define a stable way to serialize types
305 + ##
306 + ## The type specified in the descriptor can be any implementation of java.lang.reflect.Type, not necessarily a
307 + ## java.lang.Class. We can't use toString() because the return of Class#toString() is different than Class#getName().
308 + ## We can't use Type#getTypeName() either because the access to this method is restricted from Velocity. The only
309 + ## option for now is to try #getName() first and fall back on #toString() for types that are not instances of
310 + ## java.lang.Class.
311 + #set ($typeName = $descriptor.type.getName())
312 + #if ("$!typeName" == '')
313 + ## Probably not a java.lang.Class. Fall back on #toString().
314 + #set ($typeName = "$!descriptor.type")
315 + #end
316 + ## Remove whitespace from the type name in order to have a single string representation.
317 + #set ($descriptor.type = $typeName.replaceAll('\s+', ''))
318 +#end
319 +
320 +## Builds the group tree with the following structure:
321 +##
322 +## {
323 +## 'parentGroupId': {
324 +## 'id': 'parentGroupId',
325 +## 'name': 'Parent Group',
326 +## 'feature': 'someFeature',
327 +## 'groups': {
328 +## 'childGroupId': {...},
329 +## ...
330 +## }
331 +## },
332 +## ...
333 +## }
334 +#macro (handleMacroParameterGroup $groupDescriptor $groupDescriptorTree $translatedParameterDescriptor)
335 + #if ($groupDescriptor.group && $groupDescriptor.group.size() > 0)
336 + #set ($translatedParameterDescriptor.group = $groupDescriptor.group)
337 + #set ($parentGroup = $groupDescriptorTree)
338 + #foreach ($groupId in $groupDescriptor.group)
339 + #if (!$parentGroup.groups)
340 + #set ($parentGroup.groups = {})
341 + #end
342 + #set ($childGroup = $parentGroup.groups.get($groupId))
343 + #if (!$childGroup)
344 + #if ($groupId == $translatedParameterDescriptor.id)
345 + #set ($groupName = $translatedParameterDescriptor.name)
346 + #else
347 + #set ($groupTranslationKey = "${macroTranslationKey}.group.$groupId")
348 + #set ($groupName = "#maybeTranslate(""${groupTranslationKey}.name"" $groupId)")
349 + #end
350 + #set ($childGroup = {
351 + 'id': $groupId,
352 + 'name': $groupName
353 + })
354 + #set ($discard = $parentGroup.groups.put($groupId, $childGroup))
355 + #end
356 + #set ($parentGroup = $childGroup)
357 + #end
358 + #if ("$!groupDescriptor.feature" != '')
359 + #set ($parentGroup.feature = $groupDescriptor.feature)
360 + #end
361 + #elseif ($groupDescriptor.feature)
362 + ## This group is made of a single parameter. The feature then refers to this parameter.
363 + #set ($translatedParameterDescriptor.feature = $groupDescriptor.feature)
364 + #end
365 +#end
366 +
367 +#macro (getMacroParameterEditTemplate $translatedParameterDescriptor)
368 + #if ($translatedParameterDescriptor.type.getName() == 'boolean'
369 + || $translatedParameterDescriptor.type.getName() == 'java.lang.Boolean')
370 + <input type="checkbox" name="$escapetool.xml($translatedParameterDescriptor.id)" value="true"/>##
371 + ## We need to submit something in case the checkbox is not checked.
372 + <input type="hidden" name="$escapetool.xml($translatedParameterDescriptor.id)" value="false"/>
373 + #elseif ($translatedParameterDescriptor.type.isEnum())
374 + #if ($translatedParameterDescriptor.defaultValue)
375 + #set ($enumValues = $translatedParameterDescriptor.defaultValue.values())
376 + #else
377 + ## A parameter of type enum that doesn't have a default value is very unlikely. We attempt to read the list of
378 + ## possible values from the enum type in this case, which is currently forbidden, but at least it will generate
379 + ## a warning in the logs that will help us investigate the problem.
380 + #set ($enumValues = $translatedParameterDescriptor.type.getEnumConstants())
381 + #end
382 + <select name="$escapetool.xml($translatedParameterDescriptor.id)">##
383 + #foreach ($enumValue in $enumValues)
384 + #set ($value = $enumValue.name())
385 + #set ($label = "#maybeTranslate(""${parameterTranslationKey}.value.$value"" $enumValue)")
386 + <option value="$escapetool.xml($value)">$escapetool.xml($label)</option>##
387 + #end
388 + </select>
389 + #else
390 + <input type="text" name="$escapetool.xml($translatedParameterDescriptor.id)"/>
391 + #end
392 +#end
393 +
163 163  #macro (maybeTranslate $key $defaultValue)
164 164   #if ($services.localization.get($key))
165 165   $services.localization.render($key)##
... ... @@ -209,19 +209,9 @@
209 209   $response.sendError(404, $exceptiontool.getRootCauseMessage($job.status.error))
210 210   #end
211 211  #end
443 +{{/velocity}}
212 212  
213 -#macro (getMacroParameters $macroId $macroParameters)
214 - #set ($macroId = $services.rendering.resolveMacroId($macroId))
215 - #set ($macroParameters = $jsontool.fromString($macroParameters))
216 - #foreach($macroParameter in $macroParameters.entrySet())
217 - ## TODO: Do we need to take into account the macro parameter type? We could have a macro parameter that is editable
218 - ## inline but whose value is not a List<Block> but rather a String (plain text).
219 - #set ($macroParameter.value = $services.wysiwyg.fromAnnotatedXHTML($macroParameter.value, $macroId.syntax))
220 - #end
221 - #set ($data = $macroParameters)
222 -#end
223 -
224 -#set ($data = $NULL)
445 +{{velocity wiki="false"}}
225 225  #if ("$!request.action" == 'install')
226 226   #if ($services.csrf.isTokenValid($request.form_token))
227 227   #installMacroExtension($request.extensionId, $request.extensionVersion)
... ... @@ -228,18 +228,18 @@
228 228   #else
229 229   $response.sendError(403)
230 230   #end
231 -#elseif ($request.data == 'list')
232 - #getMacroList($request.syntaxId)
233 -#elseif ($request.data == 'descriptor')
234 - #maybeGetMacroDescriptor($request.macroId)
235 -#elseif ($request.data == 'macroParameters')
236 - #getMacroParameters($request.macroId, $request.macroParameters)
452 +#elseif ("$!request.data" != '')
453 + #set ($data = $NULL)
454 + #if ($request.data == 'list')
455 + #getMacroList($request.syntaxId)
456 + #elseif ($request.data == 'descriptor')
457 + #maybeGetMacroDescriptor($request.macroId)
458 + #end
459 + #if ($data)
460 + #set ($discard = $response.setContentType('application/json'))
461 + $jsontool.serialize($data)
462 + #else
463 + $response.sendError(404)
464 + #end
237 237  #end
238 -#if ($response.isCommitted())
239 - ## Do nothing.
240 -#elseif ($data)
241 - #jsonResponse($data)
242 -#elseif ("$!request.action" != '' || "$!request.data" != '')
243 - $response.sendError(404)
244 -#end
245 245  {{/velocity}}