Version 70.2 by JeromeVelociter on 2009/11/16

Show last authors
1 #startfloatingbox()
2 *Contents*
3 #toc ("2" "3" "")
4 #endfloatingbox()
5
6 Wiki macros allow macro authors to develop reusable and distributable macro modules. There is no java code involved; hence no compiling or packaging. Macro author simply needs to create a wiki page according to a particular specification and that's all!
7
8 1.1 Prerequisites
9
10 * Wiki macros are only available on XWiki Enterprise 2.0M2 and later versions
11 * Wiki macro authors need to have programming rights
12 * As of XWiki version 2.0, Wiki macros can only be defined inside the main wiki, though they can be used throughout a farm. (In the future, each wiki will have the possibility of defining its own list of macros).
13
14 1.1 Hello Macro
15
16 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.
17
18 1.1.1 Definition
19
20 Wiki macros are defined using objects of type XWiki.WikiMacroClass. You define a wiki macro by creating a new wiki page and attaching it an object of type XWiki.WikiMacroClass. This class contains following fields:
21
22 * Macro id: Id of the macro to be used by users when invoking your macro from wiki code
23
24 * Macro name: Name of the macro to be displayed on the wysiwyg editor
25
26 * Macro description: A short description of the macro to be displayed on the WYSIWYG editor
27
28 * Default category: Default category under which this macro should be listed
29
30 * Supports inline mode: Whether the macro can be used in an inline context or not
31
32 * Macro content type: Whether this macro should support a body or not
33
34 * Content description: A short description about the macro's content to be displayed on the WYSIWYG editor
35
36 * 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)
37
38 Now we can define our hello macro as shown below:
39
40 {image:macro1.png}
41
42 1.1.1 Invocation
43
44 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:
45
46 {code}
47 {{hello/}}
48 {code}
49
50 And if you view the result it would say "Hello World!" (of course).
51
52 1.1.1 Parameters
53
54 Introducing a parameter to a wiki macro is pretty straight forward; you simply need to add an object of type XWiki.WikiMacroParameterClass into your wiki macro document (one object per parameter). This class contains several fields that allow you to define your parameter clearly:
55
56 * Parameter name: Name of the parameter, users will refer this name when invoking your macro with parameters
57
58 * Parameter description: A short description of the parameter, this description will be made available on the WYSIWYG editor
59
60 * Parameter mandatory: Indicates if this particular parameter is mandatory, wiki macro will fail to execute if a mandatory parameter is missing
61
62 Now we're going to extend our hello macro with a parameter. We will introduce a parameter named ~~greetUser~~ that will indicate if the greeting message should be tailored for current user viewing the page. The definition of the parameter is show below:
63
64 {image:macro3.png}
65
66 A macro parameter defined this way can be accessed from any scripting language within the macro code. For an example, we are going to utilize our ~~greetUser~~ parameter within hello macro as below:
67
68 {image:macro4.png}
69
70 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 *$context.macro.params.greetUser*. We plan to introduce some form of direct parameter binding in near future.
71
72 Finally, we can test our new version of hello macro with the following invocation:
73
74 {code}
75 {{hello greetUser="true"/}}
76 {code}
77
78 1.1.1 A Pitfall of Optional Parameters
79
80 There is a common pitfall for using optional paramters. The following macro code contains a not so obvious bug:
81
82 {code}
83 {{velocity}}
84 #set($greetUser=$context.macro.params.greetUser)
85 #if ("true" == $greetUser && "XWiki.XWikiGuest" != "$xcontext.user" )
86 Hello $xwiki.user.email!
87 #else
88 Hello world!
89 #end
90 <img src="$image" width="$width" />
91 {code}
92
93 If we invoke it twice in a row:
94
95 {code}
96 {{hello greetUser="true" /}}
97 {{hello /}}
98 {code}
99
100 The second invocation will not print "Hello World!" as we'd expect. But it will print the same result as the first invocation. The reasons are:
101 * Macro parameters are implemented as global parameters. So, they remains the same across multiple macro invocations.
102 * If $context.macro.params.greetUser contains "null", it will not be assigned to $greetUser. This is different from C/C++ or Java.
103
104 So in order to get around it, you can use:
105
106 {code}
107 #set($greetUser="$!context.macro.params.greetUser")
108 {code}
109
110 1.1 WYSIWYG Access
111
112 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:
113
114 {image:macro2.png}
115
116 {image:macro5.png}
117
118 1.1.1 Special code for WYSIWYG edit mode
119
120 Even in edit mode, the WYSIWYG editor will execute the macro and feed the result back into the document. If your macro includes a JavaScript extension that 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 the performed transformation do not get saved. Here is how you can prevent this behavior
121
122 {code}
123 {{velocity output="no"}}
124 #if("$context.action" != "edit")
125 #set($ok = $xwiki.jsx.use("My.Extension"))
126 #end
127 ##
128 ## Rest of the code.
129 {{velocity}}
130 {code}
131
132 Check for example the [[code:Macros.LightboxMacro>>Lightbox Macro code]].
133
134 1.1 Scripting Tips
135
136 Following are few useful hints if you plan to do advanced scripting inside your wiki macros:
137
138 * Access parameters: Use the context object (Ex. $context.macro.params.param1)
139
140 * Access macro body (if your macro defines one): Use the context object (Ex. $context.macro.content)
141
142 * Access [MacroTransformationContext>http://svn.xwiki.org/svnroot/xwiki/platform/core/trunk/xwiki-rendering/xwiki-rendering-api/src/main/java/org/xwiki/rendering/transformation/MacroTransformationContext.java]: Use the context object (Ex. $context.macro.context)

Get Connected