Modifications pour le document MacroService
Modifié par Florent Charton le 2026/03/13 11:04
Depuis la version 6.1
modifié par Florent Charton
sur 2026/03/13 11:04
sur 2026/03/13 11:04
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/17.10.4]
À la version 1.1
modifié par superadmin
sur 2022/06/20 08:49
sur 2022/06/20 08:49
Commentaire de modification :
Install extension [org.xwiki.contrib:application-ckeditor-ui/1.63.1]
Résumé
-
Propriétés de la Page (2 modifications, 0 ajouts, 0 suppressions)
Détails
- Propriétés de la Page
-
- Auteur du document
-
... ... @@ -1,1 +1,1 @@ 1 - xwiki:XWiki.fcharton1 +XWiki.superadmin - Contenu
-
... ... @@ -38,66 +38,36 @@ 38 38 ## } 39 39 ## ================================================================ 40 40 #macro (getMacroList $syntaxId) 41 - 42 - ## Loads the css resources to display the macros list 43 - ## TODO: Refactor once we add support for loading css files from javascript without velocity. 44 - #if ($xcontext.action == 'get') 45 - #template('display_macros.vm') 46 - #initRequiredSkinExtensions() 47 - #end 48 - 49 - #set ($discard = $xwiki.linkx.use($services.webjars.url('selectize.js', 'css/selectize.bootstrap3.css'), 50 - {'type': 'text/css', 'rel': 'stylesheet'})) 51 - #set ($discard = $xwiki.ssfx.use('uicomponents/suggest/xwiki.selectize.css', true)) 52 - 53 - #if ($xcontext.action == 'get') 54 - #sendRequiredSkinExtensions() 55 - #end 56 - 57 57 #set ($syntax = $services.rendering.resolveSyntax($syntaxId)) 58 58 #set ($macroDescriptors = $services.rendering.getMacroDescriptors($syntax)) 43 + #if (!$macroDescriptors) 44 + ## Before XWiki 9.7RC1 we had to use APIs that require programming rights. 45 + #set ($macroDescriptors = []) 46 + #try() 47 + #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager')) 48 + #foreach ($macroId in $macroManager.getMacroIds($syntax)) 49 + #set ($macroDescriptor = $macroManager.getMacro($macroId).descriptor) 50 + #set ($discard = $macroDescriptors.add($macroDescriptor)) 51 + #end 52 + #end 53 + #end 59 59 #set ($data = {}) 60 60 #set ($allMacrosExcludedCategories = []) 61 61 #set ($discard = $allMacrosExcludedCategories.add("#maybeTranslate('rendering.macroCategory.Internal' 'Internal')")) 62 62 #set ($discard = $allMacrosExcludedCategories.add("#maybeTranslate('rendering.macroCategory.Deprecated' 'Deprecated')")) 63 63 #set ($discard = $data.put('options', { 'allMacrosExcludedCategories' : $allMacrosExcludedCategories })) 64 - ## If the current user do not want to display hidden documents, we initialize the set of hidden default 65 - ## categories. 66 - ## TODO: Make the list of hidden by default categories configurable from the administration (XWIKI-19993). 67 - #if(!$services.user.getProperties().displayHiddenDocuments()) 68 - #set ($hiddenCategories = $services.rendering.getHiddenMacroCategories()) 69 - #else 70 - #set ($hiddenCategories = []) 71 - #end 72 72 #set ($macroList = []) 73 - #set ($installedMacros = []) 74 74 #foreach ($macroDescriptor in $macroDescriptors) 75 - #set ($discard = $installedMacros.add($macroDescriptor.id.id)) 76 - 77 77 #set ($macroTranslationKey = "rendering.macro.$macroDescriptor.id") 78 - #set ($categories = []) 79 - #set ($hidden = false) 80 - #foreach ($category in $services.rendering.getMacroCategories($macroDescriptor.id)) 81 - #set ($macroCategoryTranslationKey = "rendering.macroCategory.$category") 82 - #set ($hidden = $hidden || $hiddenCategories.contains($category)) 83 - #set ($discard = $categories.add({ 84 - 'id': $category, 85 - 'label': "#maybeTranslate($macroCategoryTranslationKey $category)" 86 - })) 87 - #end 88 - 89 - #if (!$hidden) 90 - #set ($defaultCategoryTranslation = "rendering.macroCategory.${macroDescriptor.defaultCategory}") 91 - #set ($discard = $macroList.add({ 92 - 'id': $macroDescriptor.id, 93 - 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)", 94 - 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)", 95 - 'defaultCategory': "#maybeTranslate($defaultCategoryTranslation $macroDescriptor.defaultCategory)", 96 - 'categories': $categories 97 - })) 98 - #end 62 + #set ($macroCategoryTranslationKey = "rendering.macroCategory.$macroDescriptor.defaultCategory") 63 + #set ($discard = $macroList.add({ 64 + 'id': $macroDescriptor.id, 65 + 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)", 66 + 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)", 67 + 'defaultCategory': "#maybeTranslate($macroCategoryTranslationKey $macroDescriptor.defaultCategory)" 68 + })) 99 99 #end 100 - #set ($macroList = $ collectiontool.sort($macroList, 'name'))70 + #set ($macroList = $resolvedSortTool.sort($macroList, 'name')) 101 101 #set ($discard = $data.put('list', $macroList)) 102 102 ## Get macros provided by compatible available extensions 103 103 #set ($macroExtensionsList = []) ... ... @@ -114,13 +114,11 @@ 114 114 #set ($macroExtensionsMap = {}) 115 115 #foreach ($extension in $extensions) 116 116 ## TODO: move to a proper generic API to check if an extension can be installed by a given user 117 - # set($extensionInstallAllowed = $services.security.authorization.hasAccess('programming', $xcontext.userReference, $NULL)87 + #if ($services.security.authorization.hasAccess('programming') 118 118 || (($extension.type == 'xar' || $extension.type == 'webjar') 119 - && $services.security.authorization.hasAccess('admin', $xcontext.userReference, "wiki:$xcontext.database") && $services.extension.isAllowed($extension, "wiki:$xcontext.database"))) 120 - #foreach ($extensionComponent in $extension.getComponents()) 121 - #if ($extensionComponent.roleType == 'org.xwiki.rendering.macro.Macro') 122 - ## Skip macros identifiers for which a macro is already installed 123 - #if (!$installedMacros.contains($extensionComponent.roleHint)) 89 + && $services.security.authorization.hasAccess('admin', "wiki:$xcontext.database") && $services.extension.isAllowed($extension, "wiki:$xcontext.database"))) 90 + #foreach ($extensionComponent in $extension.getComponents()) 91 + #if ($extensionComponent.roleType == 'org.xwiki.rendering.macro.Macro') 124 124 #set ($discard = $macroExtensionsList.add({ 125 125 'id' : { 126 126 'id' : $extensionComponent.roleHint ... ... @@ -128,17 +128,12 @@ 128 128 'name': $extensionComponent.roleHint, 129 129 'description': $extension.summary, 130 130 'defaultCategory': '_notinstalled', 131 - 'categories': [{ 132 - 'id' :'_notinstalled', 133 - 'label': $services.localization.render('macroSelector.filter.category.notinstalled') 134 - }], 135 135 'extensionId' : $extension.id.id, 136 136 'extensionVersion' : $extension.id.version.value, 137 137 'extensionType' : $extension.type, 138 138 'extensionRecommended': $extension.recommended, 139 139 'extensionName': $extension.name, 140 - 'extensionSummary': $extension.summary, 141 - 'extensionInstallAllowed': $extensionInstallAllowed 104 + 'extensionSummary': $extension.summary 142 142 })) 143 143 #end 144 144 #end ... ... @@ -149,18 +149,236 @@ 149 149 #end 150 150 151 151 #macro (maybeGetMacroDescriptor $macroIdAsString) 152 - #template('display_macros.vm') 153 - #initRequiredSkinExtensions() 154 - #set ($macroDescriptor = $services.wysiwyg.getMacroDescriptorUI($macroIdAsString)) 115 + #set ($xmacro = $NULL) 116 + #set ($macroDescriptor = $NULL) 117 + #set ($macroId = $services.rendering.resolveMacroId($macroIdAsString)) 118 + #if ($macroId) 119 + #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId)) 120 + #if (!$macroDescriptor && $macroId.syntax) 121 + ## Try the macro id without the syntax. 122 + #set ($macroId = $services.rendering.resolveMacroId($macroId.id)) 123 + #set ($macroDescriptor = $services.rendering.getMacroDescriptor($macroId)) 124 + #end 125 + #else 126 + ## Either the macro id could not be resolved (unlikely) or we are on an older XWiki instance (before 10.10RC1) where 127 + ## we had to use APIs that require programming rights. 128 + #getMacroWithPR($macroIdAsString) 129 + #if ($xmacro) 130 + #set ($macroDescriptor = $xmacro.descriptor) 131 + #end 132 + #end 155 155 #if ($macroDescriptor) 156 - #getRequiredSkinExtensions($requiredSkinExtensions) 157 - #set ($data = { 158 - 'descriptor': $macroDescriptor, 159 - 'requiredSkinExtensions': $requiredSkinExtensions 134 + #getMacroDescriptor($macroDescriptor) 135 + #if ($xmacro) 136 + ## supportsInlineMode was not exposed on the macro descriptor before XWiki 10.10RC1. 137 + #set ($data.supportsInlineMode = $xmacro.supportsInlineMode()) 138 + #end 139 + #end 140 +#end 141 + 142 +#macro (getMacroWithPR $macroIdAsString) 143 + #set ($xmacro = $NULL) 144 + #try() 145 + #set ($macroIdFactory = $services.component.getInstance('org.xwiki.rendering.macro.MacroIdFactory')) 146 + #set ($macroId = $macroIdFactory.createMacroId($macroIdAsString)) 147 + #set ($macroManager = $services.component.getInstance('org.xwiki.rendering.macro.MacroManager')) 148 + #if ($macroManager.exists($macroId)) 149 + #set ($xmacro = $macroManager.getMacro($macroId)) 150 + #elseif ($macroId.syntax) 151 + ## Try the macro id without the syntax. 152 + #set ($macroId = $macroIdFactory.createMacroId($macroId.id)) 153 + #if ($macroManager.exists($macroId)) 154 + #set ($xmacro = $macroManager.getMacro($macroId)) 155 + #end 156 + #end 157 + #end 158 +#end 159 + 160 +#macro (getMacroDescriptor $macroDescriptor) 161 + ## Translate the macro name and description. 162 + #set ($macroTranslationKey = "rendering.macro.$macroDescriptor.id") 163 + #ckeditor_initRequiredSkinExtensions() 164 + #set ($data = { 165 + 'id': $macroDescriptor.id, 166 + 'name': "#maybeTranslate(""${macroTranslationKey}.name"" $macroDescriptor.name)", 167 + 'description': "#maybeTranslate(""${macroTranslationKey}.description"" $macroDescriptor.description)", 168 + 'defaultCategory': $macroDescriptor.defaultCategory, 169 + 'supportsInlineMode': $macroDescriptor.supportsInlineMode(), 170 + 'parameterDescriptorMap': {} 171 + }) 172 + #if ($macroDescriptor.contentDescriptor) 173 + ## Translate the content label and description. 174 + ## Treat the macro content as if it is the last macro parameter. 175 + #set ($data.contentDescriptor = { 176 + 'name': "#maybeTranslate('rendering.macroContent' 'Content')", 177 + 'description': "#maybeTranslate(""${macroTranslationKey}.content.description"" 178 + $macroDescriptor.contentDescriptor.description)", 179 + 'mandatory': $macroDescriptor.contentDescriptor.mandatory, 180 + 'deprecated': $macroDescriptor.contentDescriptor.deprecated, 181 + 'advanced': $macroDescriptor.contentDescriptor.advanced, 182 + 'defaultValue': $macroDescriptor.contentDescriptor.defaultValue, 183 + 'type': $macroDescriptor.contentDescriptor.type, 184 + 'editTemplate': '<textarea name="$content" rows="7"></textarea>', 185 + 'index': $macroDescriptor.parameterDescriptorMap.size() 160 160 }) 187 + #fixDescriptorType($data.contentDescriptor) 161 161 #end 189 + #set ($groupDescriptorTree = {}) 190 + #foreach ($entry in $macroDescriptor.parameterDescriptorMap.entrySet()) 191 + #set ($parameterDescriptor = $entry.value) 192 + ## Translate the parameter name and description. 193 + #set ($parameterTranslationKey = "${macroTranslationKey}.parameter.$parameterDescriptor.id") 194 + ## Note: The displayHidden parameter is new in XWiki 12.4RC1 so make sure we set 'hidden' to false if it doesn't 195 + ## exist 196 + #if ("$!parameterDescriptor.displayHidden" != '') 197 + #set ($parameterHidden = $parameterDescriptor.displayHidden) 198 + #else 199 + #set ($parameterHidden = false) 200 + #end 201 + #set ($translatedParameterDescriptor = { 202 + 'id': $parameterDescriptor.id, 203 + 'name': "#maybeTranslate(""${parameterTranslationKey}.name"" $parameterDescriptor.name)", 204 + 'description': "#maybeTranslate(""${parameterTranslationKey}.description"" $parameterDescriptor.description)", 205 + 'mandatory': $parameterDescriptor.mandatory, 206 + 'deprecated': $parameterDescriptor.deprecated, 207 + 'advanced': $parameterDescriptor.advanced, 208 + 'defaultValue': $parameterDescriptor.defaultValue, 209 + 'type': $parameterDescriptor.displayType, 210 + 'hidden' : $parameterHidden, 211 + 'index': $foreach.index 212 + }) 213 + #if ("$!translatedParameterDescriptor.type" == '') 214 + ## displayType is not available before XWiki 11.0 so we need to fall back on parameterType. 215 + #set ($translatedParameterDescriptor.type = $parameterDescriptor.parameterType) 216 + #end 217 + #set ($translatedParameterDescriptor.caseInsensitive = $translatedParameterDescriptor.type.isEnum()) 218 + #set ($groupDescriptor = $parameterDescriptor.groupDescriptor) 219 + #if ($groupDescriptor) 220 + #handleMacroParameterGroup($groupDescriptor $groupDescriptorTree $translatedParameterDescriptor) 221 + #end 222 + #if ($translatedParameterDescriptor.type.getName() == 'java.lang.String' 223 + && ($parameterDescriptor.defaultValue == 'false' || $parameterDescriptor.defaultValue == 'true') 224 + && $macroDescriptor.parametersBeanClass.getSimpleName() == 'WikiMacroParameters') 225 + #set ($translatedParameterDescriptor.defaultValue = $parameterDescriptor.defaultValue == 'true') 226 + #set ($translatedParameterDescriptor.type = $translatedParameterDescriptor.defaultValue.getClass()) 227 + #end 228 + #set ($htmlDisplayerParameters = {'name': $parameterDescriptor.id}) 229 + #if ($translatedParameterDescriptor.group) 230 + #set ($discard = $htmlDisplayerParameters.put('data-property-group', 231 + $stringtool.join($translatedParameterDescriptor.group, '/'))) 232 + #end 233 + #set ($translatedParameterDescriptor.editTemplate = $services.display.html.display( 234 + $translatedParameterDescriptor.type, $translatedParameterDescriptor.defaultValue, $htmlDisplayerParameters, 'edit' 235 + )) 236 + #if ("$!translatedParameterDescriptor.editTemplate" == '') 237 + #set ($translatedParameterDescriptor.editTemplate = "#getMacroParameterEditTemplate( 238 + $translatedParameterDescriptor)") 239 + #end 240 + #set ($translatedParameterDescriptor.editTemplate = $translatedParameterDescriptor.editTemplate.trim()) 241 + #fixDescriptorType($translatedParameterDescriptor) 242 + ## Make sure the key is lowercase (for XWiki <9.0). 243 + ## See XWIKI-13990: Inconsistency between Java-based and Wiki-based rendering macros regarding the parameter 244 + ## descriptor map keys 245 + #set ($discard = $data.parameterDescriptorMap.put($entry.key.toLowerCase(), $translatedParameterDescriptor)) 246 + #end 247 + #if ($groupDescriptorTree.groups) 248 + #set ($data.groupDescriptorTree = $groupDescriptorTree.groups) 249 + #end 250 + #set ($data.requiredSkinExtensions = "#ckeditor_getRequiredSkinExtensions()") 162 162 #end 163 163 253 +#macro (fixDescriptorType $descriptor) 254 + ## The goal of this code is to obtain a normalized string representation of the type specified in the descriptor. 255 + ## See XCOMMONS-1583: Define a stable way to serialize types 256 + ## 257 + ## The type specified in the descriptor can be any implementation of java.lang.reflect.Type, not necessarily a 258 + ## java.lang.Class. We can't use toString() because the return of Class#toString() is different than Class#getName(). 259 + ## We can't use Type#getTypeName() either because the access to this method is restricted from Velocity. The only 260 + ## option for now is to try #getName() first and fall back on #toString() for types that are not instances of 261 + ## java.lang.Class. 262 + #set ($typeName = $descriptor.type.getName()) 263 + #if ("$!typeName" == '') 264 + ## Probably not a java.lang.Class. Fall back on #toString(). 265 + #set ($typeName = "$!descriptor.type") 266 + #end 267 + ## Remove whitespace from the type name in order to have a single string representation. 268 + #set ($descriptor.type = $typeName.replaceAll('\s+', '')) 269 +#end 270 + 271 +## Builds the group tree with the following structure: 272 +## 273 +## { 274 +## 'parentGroupId': { 275 +## 'id': 'parentGroupId', 276 +## 'name': 'Parent Group', 277 +## 'feature': 'someFeature', 278 +## 'groups': { 279 +## 'childGroupId': {...}, 280 +## ... 281 +## } 282 +## }, 283 +## ... 284 +## } 285 +#macro (handleMacroParameterGroup $groupDescriptor $groupDescriptorTree $translatedParameterDescriptor) 286 + #if ($groupDescriptor.group && $groupDescriptor.group.size() > 0) 287 + #set ($translatedParameterDescriptor.group = $groupDescriptor.group) 288 + #set ($parentGroup = $groupDescriptorTree) 289 + #foreach ($groupId in $groupDescriptor.group) 290 + #if (!$parentGroup.groups) 291 + #set ($parentGroup.groups = {}) 292 + #end 293 + #set ($childGroup = $parentGroup.groups.get($groupId)) 294 + #if (!$childGroup) 295 + #if ($groupId == $translatedParameterDescriptor.id) 296 + #set ($groupName = $translatedParameterDescriptor.name) 297 + #else 298 + #set ($groupTranslationKey = "${macroTranslationKey}.group.$groupId") 299 + #set ($groupName = "#maybeTranslate(""${groupTranslationKey}.name"" $groupId)") 300 + #end 301 + #set ($childGroup = { 302 + 'id': $groupId, 303 + 'name': $groupName 304 + }) 305 + #set ($discard = $parentGroup.groups.put($groupId, $childGroup)) 306 + #end 307 + #set ($parentGroup = $childGroup) 308 + #end 309 + #if ("$!groupDescriptor.feature" != '') 310 + #set ($parentGroup.feature = $groupDescriptor.feature) 311 + #end 312 + #elseif ($groupDescriptor.feature) 313 + ## This group is made of a single parameter. The feature then refers to this parameter. 314 + #set ($translatedParameterDescriptor.feature = $groupDescriptor.feature) 315 + #end 316 +#end 317 + 318 +#macro (getMacroParameterEditTemplate $translatedParameterDescriptor) 319 + #if ($translatedParameterDescriptor.type.getName() == 'boolean' 320 + || $translatedParameterDescriptor.type.getName() == 'java.lang.Boolean') 321 + <input type="checkbox" name="$escapetool.xml($translatedParameterDescriptor.id)" value="true"/>## 322 + ## We need to submit something in case the checkbox is not checked. 323 + <input type="hidden" name="$escapetool.xml($translatedParameterDescriptor.id)" value="false"/> 324 + #elseif ($translatedParameterDescriptor.type.isEnum()) 325 + #if ($translatedParameterDescriptor.defaultValue) 326 + #set ($enumValues = $translatedParameterDescriptor.defaultValue.values()) 327 + #else 328 + ## A parameter of type enum that doesn't have a default value is very unlikely. We attempt to read the list of 329 + ## possible values from the enum type in this case, which is currently forbidden, but at least it will generate 330 + ## a warning in the logs that will help us investigate the problem. 331 + #set ($enumValues = $translatedParameterDescriptor.type.getEnumConstants()) 332 + #end 333 + <select name="$escapetool.xml($translatedParameterDescriptor.id)">## 334 + #foreach ($enumValue in $enumValues) 335 + #set ($value = $enumValue.name()) 336 + #set ($label = "#maybeTranslate(""${parameterTranslationKey}.value.$value"" $enumValue)") 337 + <option value="$escapetool.xml($value)">$escapetool.xml($label)</option>## 338 + #end 339 + </select> 340 + #else 341 + <input type="text" name="$escapetool.xml($translatedParameterDescriptor.id)"/> 342 + #end 343 +#end 344 + 164 164 #macro (maybeTranslate $key $defaultValue) 165 165 #if ($services.localization.get($key)) 166 166 $services.localization.render($key)## ... ... @@ -210,19 +210,9 @@ 210 210 $response.sendError(404, $exceptiontool.getRootCauseMessage($job.status.error)) 211 211 #end 212 212 #end 394 +{{/velocity}} 213 213 214 -#macro (getMacroParameters $macroId $macroParameters) 215 - #set ($macroId = $services.rendering.resolveMacroId($macroId)) 216 - #set ($macroParameters = $jsontool.fromString($macroParameters)) 217 - #foreach($macroParameter in $macroParameters.entrySet()) 218 - ## TODO: Do we need to take into account the macro parameter type? We could have a macro parameter that is editable 219 - ## inline but whose value is not a List<Block> but rather a String (plain text). 220 - #set ($macroParameter.value = $services.wysiwyg.fromAnnotatedXHTML($macroParameter.value, $macroId.syntax)) 221 - #end 222 - #set ($data = $macroParameters) 223 -#end 224 - 225 -#set ($data = $NULL) 396 +{{velocity wiki="false"}} 226 226 #if ("$!request.action" == 'install') 227 227 #if ($services.csrf.isTokenValid($request.form_token)) 228 228 #installMacroExtension($request.extensionId, $request.extensionVersion) ... ... @@ -229,18 +229,18 @@ 229 229 #else 230 230 $response.sendError(403) 231 231 #end 232 -#elseif ($request.data == 'list') 233 - #getMacroList($request.syntaxId) 234 -#elseif ($request.data == 'descriptor') 235 - #maybeGetMacroDescriptor($request.macroId) 236 -#elseif ($request.data == 'macroParameters') 237 - #getMacroParameters($request.macroId, $request.macroParameters) 403 +#elseif ("$!request.data" != '') 404 + #set ($data = $NULL) 405 + #if ($request.data == 'list') 406 + #getMacroList($request.syntaxId) 407 + #elseif ($request.data == 'descriptor') 408 + #maybeGetMacroDescriptor($request.macroId) 409 + #end 410 + #if ($data) 411 + #set ($discard = $response.setContentType('application/json')) 412 + $jsontool.serialize($data) 413 + #else 414 + $response.sendError(404) 415 + #end 238 238 #end 239 -#if ($response.isCommitted()) 240 - ## Do nothing. 241 -#elseif ($data) 242 - #jsonResponse($data) 243 -#elseif ("$!request.action" != '' || "$!request.data" != '') 244 - $response.sendError(404) 245 -#end 246 246 {{/velocity}}