Changes for page Writing XWiki Rendering Macros in wiki pages
Last modified by Simon Urli on 2023/10/10
Change comment:
There is no comment for this version
Summary
-
Page properties (2 modified, 0 added, 0 removed)
Details
- Page properties
-
- Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. VincentMassol1 +XWiki.ThomasMortagne - Content
-
... ... @@ -6,20 +6,6 @@ 6 6 7 7 This page is a tutorial but you can also access the [[reference documentation for the Wiki Macro feature>>doc:extensions:Extension.WikiMacroStore.WebHome]]. 8 8 9 -= Macro Visibility and Rights = 10 - 11 -There are 3 levels of visibility for a macro: 12 - 13 -* ##Global## 14 -** on main wiki (or {{info}}before XWiki 10.4RC1{{/info}}) the macro will be available in all the pages of all the (sub)wikis. Requires the macro author to have **Programming Rights** 15 -** on subwiki {{info}}in 10.4RC1+{{/info}} synonym of ##Current Wiki## visibility 16 -* ##Current Wiki##, which means that the macro will be available in all the pages of the wiki the macro is in. Requires the macro author to have **Admin Rights** 17 -* ##Current User##, which means that the macro will only be available to the user who is its author. No special rights required. 18 - 19 -== Using protected API in wiki macros == 20 - 21 -Also, if the macro needs to use [[protected API>>platform:DevGuide.Scripting||anchor="HXWikiCoreAccess"]], the author of the macro will need to have programming rights. Note that the macro will always be executed with the rights of its author, and not with the rights of the author of the calling document (the document using the macro). Specifically, if the macro uses protected API, only the macro author needs to have programming rights, not all the authors of the documents that call this macro. 22 - 23 23 = Hello Macro = 24 24 25 25 We are going to start with a very simple xwiki/2.0 wiki macro which prints a greeting message to the document content. It isn't a very useful macro but the idea is to get you familiarised with the wiki macro creation process. ... ... @@ -32,7 +32,6 @@ 32 32 There can be only one object of type ##XWiki.WikiMacroClass## per wiki page (if you add more only the first will be used). 33 33 {{/warning}} 34 34 35 - 36 36 This class contains the following fields: 37 37 38 38 * **Macro id**: Id of the macro to be used by users when invoking your macro from wiki code ... ... @@ -41,9 +41,10 @@ 41 41 * **Default category**: Default category under which this macro should be listed 42 42 * **Supports inline mode**: Whether the macro can be used in an inline context or not 43 43 * **Macro Content availability**: {{warning}}before 11.5RC1 this was called **Macro Content Type**{{/warning}} whether this macro should support a body or not 44 -* **Macro content type**: {{warning}}this field has been renamed **Macro Content Availability** since 11.5RC1{{/warning}} the type of accepted content: two values are proposed, ##WIKI## if this content should be editable like a wiki content, or ##UNKNOWN## if it should be displayed like a plain text. It's also possible to specify a custom java type such as {{code language= 'java'}}java.util.List<java.lang.String>{{/code}}. Leaving the field blank is equivalent to ##UNKWOWN## value.29 +* **Macro content type**: {{warning}}this field has been renamed **Macro Content Availability** since 11.5RC1{{/warning}} the type of accepted content: two values are proposed, ##WIKI## if this content should be editable like a wiki content, or ##UNKNOWN## if it should be displayed like a plain text. It's also possible to specify a custom java type such as {{code language="java"}}java.util.List<java.lang.String>{{/code}}. Leaving the field blank is equivalent to ##UNKWOWN## value. 45 45 * **Content description**: A short description about the macro's content to be displayed on the WYSIWYG editor 46 46 * **Macro code**: The actual wiki code that will be evaluated when the macro is executed, can be any xwiki content (should be in the same syntax as the document) 32 +* **Priority**: {{info}}Since 13.1{{/info}} The priority of execution relative to the other Macros. The lowest values have the highest priorities and execute first. For example a Macro with a priority of 100 will execute before one with a priority of 500. The default value is 1000. 47 47 * **Asynchronous rendering**: {{info}}Since 10.10{{/info}} Enabled or disable asynchronous rendering of the panel. Disabled by default. 48 48 * **Cached**: {{info}}Since 10.10{{/info}} Indicate if the result of the execution of the element should be cached. Disabled by default. 49 49 * **Context elements**: {{info}}Since 10.10{{/info}} The context information required during the execution of the extension (current user, current document, etc.). It's also used to generate the cache key. ... ... @@ -56,7 +56,7 @@ 56 56 57 57 A wiki macro can be invoked just like any other macro is invoked. Since we are writing a xwiki/2.0 wiki macro, we can invoke our **hello macro** as below: 58 58 59 -{{code language= 'none'}}45 +{{code language="none"}} 60 60 {{hello/}} 61 61 {{/code}} 62 62 ... ... @@ -64,7 +64,7 @@ 64 64 65 65 == Content == 66 66 67 -{{version since= '11.4RC1'}}53 +{{version since="11.4RC1"}} 68 68 There are two ways to insert the content of the wiki macro. 69 69 70 70 * The easiest way is to use a dedicated macro in the body of the wikimacro:((( ... ... @@ -81,7 +81,7 @@ 81 81 ))) 82 82 {{/version}} 83 83 84 -For more details, see the [[Scripting Tips section below>> platform:DevGuide.WikiMacroTutorial||anchor="HScriptingTips"]].70 +For more details, see the [[Scripting Tips section below>>||anchor="HScriptingTips"]]. 85 85 86 86 == Parameters == 87 87 ... ... @@ -100,7 +100,7 @@ 100 100 101 101 A macro parameter defined this way can be accessed from any scripting language within the macro code. For example, we are going to utilize our //greetUser// parameter within **hello macro** as shown below: 102 102 103 -{{code language= 'none'}}89 +{{code language="none"}} 104 104 {{velocity}} 105 105 #if ($wikimacro.parameters.greetUser && "XWiki.XWikiGuest" != "$xcontext.user") 106 106 Hello $xwiki.user.email! ... ... @@ -113,17 +113,17 @@ 113 113 As you might have realized already, direct binding of parameters is not supported at the moment. That is, you cannot access //greetUser// parameter with **$greetUser**. Instead you must use **$wikimacro.parameters.greetUser**. We plan to introduce some form of direct parameter binding in near future. 114 114 115 115 Since {{info}}11.5RC1{{/info}}, it is also possible to display the content of a macro parameter by using a dedicated macro: 116 -{{code language= 'none'}}Hello {{wikimacroparameter name="greeUsers" /}}{{/code}}102 +{{code language="none"}}Hello {{wikimacroparameter name="greeUsers" /}}{{/code}} 117 117 118 118 Finally, we can test our new version of **hello macro** with the following invocation: 119 119 120 -{{code language= 'none'}}106 +{{code language="none"}} 121 121 {{hello greetUser="true"/}} 122 122 {{/code}} 123 123 124 124 If you want to call the new version of the **hello macro** with a parameter from a variable you will need to wrap the call in a velocity macro like this: 125 125 126 -{{code language= 'none'}}112 +{{code language="none"}} 127 127 {{velocity}} 128 128 #set ($greet = true) 129 129 {{hello greetUser="$greet"/}} ... ... @@ -134,7 +134,7 @@ 134 134 135 135 When your macro is ready, you might want to provide the description of the macro and its parameters in different languages. For that, you need to create a set of translation keys and values (as described [[here>>platform:DevGuide.InternationalizingApplications]]) and then just use the following convention for the keys you add in this storage (no modification is needed on the macro itself, the association of the translations to the macro is done based on a convention of the form of the translation keys): 136 136 137 -{{code language= 'properties'}}123 +{{code language="properties"}} 138 138 rendering.macro.<macro id>.name=Name of the macro, displayed in the macros list in the macros wizard 139 139 rendering.macro.<macro id>.description=Description of the macro, displayed as a help in the macros list in the macros wizard 140 140 ... ... @@ -146,7 +146,7 @@ 146 146 147 147 In our example, french translations would be something like this: 148 148 149 -{{code language= 'properties'}}135 +{{code language="properties"}} 150 150 rendering.macro.hello.name=Macro pour dire bonjour 151 151 rendering.macro.hello.description=Ceci est une macro qui va dire "Bonjour" a l'utilisateur 152 152 rendering.macro.hello.parameter.greetUser.name=Personnaliser le message ... ... @@ -153,6 +153,24 @@ 153 153 rendering.macro.hello.parameter.greetUser.description=Personnaliser le message pour l'utilisateur courant en train de visualiser la page. Les valeurs possibles sont "true" (oui) et "false" (non). 154 154 {{/code}} 155 155 142 += Macro Visibility and Rights = 143 + 144 +There are 3 levels of visibility for a macro: 145 + 146 +* ##Global## 147 +** on main wiki (or {{info}}before XWiki 10.4RC1{{/info}}) the macro will be available in all the pages of all the (sub)wikis. Requires the macro author to have **Programming Rights** 148 +** on subwiki {{info}}in 10.4RC1+{{/info}} synonym of ##Current Wiki## visibility 149 +* ##Current Wiki##, which means that the macro will be available in all the pages of the wiki the macro is in. Requires the macro author to have **Admin Rights** 150 +* ##Current User##, which means that the macro will only be available to the user who is its author. No special rights required. 151 + 152 +== Using protected API in wiki macros == 153 + 154 +Also, if the macro needs to use [[protected API>>platform:DevGuide.Scripting||anchor="HXWikiCoreAccess"]], the author of the macro will need to have programming rights. Note that the macro will always be executed with the rights of its author, and not with the rights of the author of the calling document (the document using the macro). Specifically, if the macro uses protected API, only the macro author needs to have programming rights, not all the authors of the documents that call this macro. 155 + 156 += Bindings = 157 + 158 +See all availalbe bindings in [[the reference documentation page>>doc:extensions:Extension.WikiMacroStore.WebHome||anchor="HBindings"]]. 159 + 156 156 = WYSIWYG Access = 157 157 158 158 A wiki macros is treated just like any other rendering macro in the system. As such, the moment you save your wiki macro it will be available to the users through the WYSIWYG editor's **Insert Macro** dialog box: ... ... @@ -165,7 +165,7 @@ 165 165 166 166 Even in edit mode, the WYSIWYG editor will execute the macro and feed the result back into the document. If your macro use some JSX, these will not be loaded. But, if your macro produce some Javascript that use those JSX or manipulate the document's DOM (injecting new elements, moving existing elements, removing elements, etc.), you may want to protect the content in WYSIWYG edit mode in order to prevent the performed transformation to get saved. Here is how you can prevent this behavior: 167 167 168 -{{code language= 'velocity'}}172 +{{code language="velocity"}} 169 169 {{velocity}} 170 170 #if("$xcontext.action" != "edit") 171 171 {{html}} ... ... @@ -183,7 +183,7 @@ 183 183 184 184 == WYSIWYG editing of macro content or parameter == 185 185 186 -As specified above you can use the dedicated macros {{code language= 'none'}}{{wikimacrocontent/}}{{/code}} and {{code language='none'}}{{wikimacroparameter name="foo"/}}{{/code}} to allow the users of your macro to be able to edit the values of the macro directly in the WYSIWYG editor once the macro is inserted.190 +As specified above you can use the dedicated macros {{code language="none"}}{{wikimacrocontent/}}{{/code}} and {{code language="none"}}{{wikimacroparameter name="foo"/}}{{/code}} to allow the users of your macro to be able to edit the values of the macro directly in the WYSIWYG editor once the macro is inserted. 187 187 Note that this is currently only possible if you specified that the macro content (or parameter) type is ##WIKI## type. 188 188 189 189 {{info}} ... ... @@ -194,9 +194,8 @@ 194 194 195 195 Following are a few useful hints if you plan to do advanced scripting inside your wiki macros: 196 196 197 -* See all bindings in [[the reference documentation page>>doc:extensions:Extension.WikiMacroStore.WebHome||anchor="HBindings"]]. 198 198 * Since 2.4M1, it's possible to directly return the desired list of rendering blocks without having to render them first to let them be parsed back by the macro transformation. The benefits are that it could be a lots quicker and most of all it means supporting syntax which does not provide any renderer. It also makes it possible to generate some XDOM which is impossible to write in any some syntax. For example the following wiki macro is generating a LinkBlock targeting a relative URL:((( 199 -{{code language= 'groovy'}}202 +{{code language="groovy"}} 200 200 {{groovy}} 201 201 import java.util.Collections; 202 202 import org.xwiki.rendering.listener.Link; ... ... @@ -216,7 +216,7 @@ 216 216 {{/code}} 217 217 ))) 218 218 * If you are using ##$wikimacro.content## in your velocity macro, that content will not be able to support scripting, since nested scripting is not supported. To workaround that limitation, thanks to the above, you may do the parsing yourself using the rendering service. Here is a small sample:((( 219 -{{code language= 'velocity'}}222 +{{code language="velocity"}} 220 220 {{velocity output="no"}} 221 221 ## get the macro content in a velocity string 222 222 #set($wikiresult = $wikimacro.content) ... ... @@ -238,7 +238,7 @@ 238 238 239 239 There is a common pitfall for using optional paramters. The following macro code contains a not so obvious bug: 240 240 241 -{{code languege= 'velocity'}}244 +{{code languege="velocity"}} 242 242 {{velocity}} 243 243 #set($greetUser=$xcontext.macro.params.greetUser) 244 244 #if ("true" == $greetUser && "XWiki.XWikiGuest" != "$xcontext.user" ) ... ... @@ -251,7 +251,7 @@ 251 251 252 252 If we invoke it twice in a row: 253 253 254 -{{code language= 'none'}}257 +{{code language="none"}} 255 255 {{hello greetUser="true" /}} 256 256 {{hello /}} 257 257 {{/code}} ... ... @@ -263,6 +263,6 @@ 263 263 264 264 So in order to get around it, you can use: 265 265 266 -{{code language= 'none'}}269 +{{code language="none"}} 267 267 #set($greetUser="$!xcontext.macro.params.greetUser") 268 268 {{/code}}