Wiki source code of Wiki Macros
Last modified by superadmin on 2026/10/12 13:22
Hide last authors
| author | version | line-number | content |
|---|---|---|---|
![]() |
4.1 | 1 | A wiki macro is a rendering macro written as a wiki page instead of Java code: nothing to compile, no jar to package and no restart. Its author creates a page, attaches an ##XWiki.WikiMacroClass## object to it, and the macro is available as soon as the page is saved. |
| 2 | |||
| 3 | [[Write a Macro in a Wiki Page>>doc:documentation.xs.dev.rendering-macros.wiki-macros.write-wiki-macro.WebHome]] walks through that, [[Wiki Macro Fields>>doc:documentation.xs.dev.rendering-macros.wiki-macros.wiki-macro-fields.WebHome]] lists every field of the two XClasses involved, and the [[Wiki Macro Store>>doc:extensions:Extension.WikiMacroStore.WebHome]] is the reference documentation of the feature itself. | ||
| 4 | |||
| 5 | {{warning}} | ||
| 6 | A page carries **one** ##XWiki.WikiMacroClass## object. Add a second one and only the first is used. | ||
| 7 | {{/warning}} | ||
| 8 | |||
| 9 | == Visibility and rights == | ||
| 10 | |||
| 11 | The "Macro visibility" field says where the macro can be used, and what rights its author needs for that: | ||
| 12 | |||
| 13 | |=Visibility|=Scope|=Rights required | ||
| 14 | |##Global##|Every page of every wiki of the farm, when the macro is defined on the main wiki. On a subwiki it means the same as ##Current Wiki##.|Programming Rights | ||
| 15 | |##Current Wiki##|Every page of the wiki that defines the macro.|Admin Rights | ||
| 16 | |##Current User##|The pages of its own author only.|None | ||
| 17 | |||
| 18 | A macro that uses [[protected API>>doc:Documentation.DevGuide.Scripting.WebHome||anchor="HXWikiCoreAccess"]] needs its author to have Programming Rights as well. | ||
| 19 | |||
| 20 | A wiki macro always executes with the rights of **its own author**, never with those of the author of the page that calls it. So the author of the macro is the only one who needs those rights, however many pages use it. | ||
| 21 | |||
| 22 | == Bindings == | ||
| 23 | |||
| 24 | The [[usual scripting bindings>>doc:extensions:Extension.Script Macro||anchor="HBindings"]] are available in the macro code, and the [[Wiki Macro Store>>doc:extensions:Extension.WikiMacroStore.WebHome||anchor="HBindings"]] documents the ones wiki macros add, such as ##$wikimacro##. | ||
| 25 | |||
| 26 | They are bound to the page where the macro is **called**, not to the page that defines it: ##$doc## is the calling page. That is what lets one macro produce a different result on every page that uses it. | ||
| 27 | |||
| 28 | == In the WYSIWYG editor == | ||
| 29 | |||
| 30 | A wiki macro is treated like any other rendering macro, and it is offered in the editor's macro list, under "Insert" then "Other Macros". | ||
| 31 | |||
| 32 | {{image reference="insert-macro-dialog.png" size="large" alt="The Select Macro dialog of the WYSIWYG editor, its filter holding hello and the Hello macro of the Content category listed below"/}} | ||
| 33 | |||
| 34 | Picking it opens a form built from the macro's own fields: the content, described by the "Content description" field, and one entry per ##XWiki.WikiMacroParameterClass## object. The name, the description and the labels it shows are the macro's own, unless [[they are translated>>doc:documentation.xs.dev.rendering-macros.wiki-macros.translate-wiki-macro.WebHome]] into the language of the reader. | ||
| 35 | |||
| 36 | {{image reference="macro-parameter-form.png" size="large" alt="The Edit Macro dialog of the Hello macro, with its content field and its greetUser parameter below"/}} | ||
| 37 | |||
| 38 | === Editing the content and the parameters in place === | ||
| 39 | |||
| 40 | A macro that displays its own content with ##~{~{wikimacrocontent/~}~}##, or one of its parameters with ##~{~{wikimacroparameter name="..."/~}~}##, lets the **users** of the macro edit those values in the page itself rather than in that form. See the [[CKEditor integration>>doc:extensions:Extension.CKEditor Integration.WebHome||anchor="HWikiMacros"]]. | ||
| 41 | |||
| 42 | It works only where the content, or the parameter, is of type ##Wiki##. | ||
| 43 | |||
| 44 | {{info}} | ||
| 45 | A macro used inside a sentence rather than on its own line cannot be edited in place: see [[CKEDITOR-248>>https://jira.xwiki.org/browse/CKEDITOR-248]]. | ||
| 46 | {{/info}} | ||
| 47 | |||
| 48 | === Macros that generate JavaScript === | ||
| 49 | |||
| 50 | The editor **executes the macro in edit mode too**, and feeds the result back into the document being edited. JavaScript skin extensions are not loaded there, so a macro whose script rewrites the page can have its own output saved into the document. Guard that code with the current action: | ||
| 51 | |||
| 52 | {{code language="velocity"}} | ||
| 53 | {{velocity}} | ||
| 54 | #if("$xcontext.action" != "edit") | ||
| 55 | {{html}} | ||
| 56 | <script> | ||
| 57 | // the code that must not run while the page is being edited | ||
| 58 | </script> | ||
| 59 | {{/html}} | ||
| 60 | #end | ||
| 61 | {{/velocity}} | ||
| 62 | {{/code}} | ||
| 63 | |||
| 64 | == Returning blocks directly == | ||
| 65 | |||
| 66 | Rather than rendering its result to wiki syntax that the macro transformation parses back, a macro can assign the rendering blocks themselves to ##$wikimacro.result##. It is faster, it works for syntaxes that have no renderer, and it can produce an XDOM that no syntax is able to express. | ||
| 67 | |||
| 68 | This Groovy macro returns a link to a relative URL: | ||
| 69 | |||
| 70 | {{code language="groovy"}} | ||
| 71 | {{groovy}} | ||
| 72 | import org.xwiki.rendering.block.LinkBlock | ||
| 73 | import org.xwiki.rendering.block.WordBlock | ||
| 74 | import org.xwiki.rendering.listener.reference.ResourceReference | ||
| 75 | import org.xwiki.rendering.listener.reference.ResourceType | ||
| 76 | |||
| 77 | def reference = new ResourceReference("/xwiki/bin/edit/Main/WebHome", ResourceType.PATH) | ||
| 78 | def linkBlock = new LinkBlock(List.of(new WordBlock("Edit home page")), reference, false) | ||
| 79 | |||
| 80 | wikimacro.result = List.of(linkBlock) | ||
| 81 | {{/groovy}} | ||
| 82 | {{/code}} | ||
| 83 | |||
| 84 | A macro can also parse content into an XDOM itself, through the rendering script service. This one wraps its own content in a styled group: | ||
| 85 | |||
| 86 | {{code language="velocity"}} | ||
| 87 | {{velocity output="no"}} | ||
| 88 | ## read the content the macro was called with | ||
| 89 | #set($wikiresult = $wikimacro.content) | ||
| 90 | ## wrap it | ||
| 91 | #set($wikiresult = "(% class='newstyle' %)((($wikiresult)))") | ||
| 92 | ## parse it, and return the blocks of the result | ||
| 93 | #set($wikimacro.result = $services.rendering.parse($wikiresult, $xwiki.getCurrentContentSyntaxId()).getChildren()) | ||
| 94 | {{/velocity}} | ||
| 95 | {{/code}} |
