Show last authors
1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc/}}
3 {{/box}}
4
5 Scripting allows you to create basic to complex web applications at the XWiki page (or view) layer without the need for compiling code or deploying software components. In other words, you can use scripting syntax in addition to wiki and HTML syntax as the contents of an XWiki page.
6
7 XWiki integrates [[jsr-223>>http://jcp.org/en/jsr/detail?id=223]] scripting. You can script using several available languages by using one of the following macros:
8
9 * [[Velocity Macro>>extensions:Extension.Velocity Macro]] (installed by default in XWiki Enterprise)
10 * [[Groovy Macro>>extensions:Extension.Groovy Macro]] (installed by default in XWiki Enterprise)
11 * [[Python Macro>>extensions:Extension.Python Macro]] (installed by default in XWiki Enterprise)
12 * [[Ruby Macro>>extensions:Extension.Ruby Macro]] (not installed by default in XWiki Enterprise)
13 * [[PHP Macro>>extensions:Extension.PHP Macro]] (not installed by default in XWiki Enterprise)
14
15 = Choosing a Scripting language =
16
17 Since XWiki supports several scripting languages you might be wondering which one to use. Most of the code written by XWiki developers is in Velocity, with a few more complex extensions written in Groovy; these two are thoroughly tried and tested, so they are both a safe bet. The other languages //should// work just as well, but there are less developers that could help answering any questions.
18
19 == Velocity ==
20
21 The first thing to know is that Velocity is different from the other scripting languages on 2 aspects:
22
23 * It's a templating language rather than a pure scripting language, which means that its content is actually wiki markup interspersed with Velocity directives, whereas pure scripting languages are written in that language and they need to explicitly output wiki markup. For example:(((
24 Velocity:
25
26 {{code}}
27 {{velocity}}
28 Your username is $xcontext.getUser(), welcome to the site.
29 {{/velocity}}
30 {{/code}}
31
32 Groovy:
33
34 {{code}}
35 {{groovy}}
36 println("Your username is " + xcontext.getUser() + " welcome to the site.");
37 {{/groovy}}
38 {{/code}}
39 )))
40 * It doesn't require special permissions since it runs in a Sandbox, with access to only a few safe objects, and each API call will check the rights configured in the wiki, forbidding access to resources or actions that the current user shouldn't be allowed to retrieve/perform. Other scripting language require the user that wrote the script to have Programming Rights to execute them, but except this initial precondition, access is granted to all the resources on the server. Note that starting with XWiki 4.1 we've introduced a [[Sandbox for Groovy>>platform:AdminGuide.Configuration#HSecuringGroovyScripts]] too, but it's still in an early stage.
41
42 Being a templating engine, Velocity doesn't offer many means of structuring code. In fact, there's only one useful directive in this regard, ###macro##. However, because it is a templating engine, its syntax is much simpler and easier to understand by non-developers, which means that it's accessible to a wider range of users, without a serious background in programming.
43
44 Without programming rights, it's impossible to instantiate new objects, except literals and those safely offered by the XWiki APIs. Nevertheless, the XWiki API is powerful enough to allow a wide range of applications to be safely developed, if "the XWiki way" is properly followed.
45
46 Velocity is also available in some other parts of XWiki: it is the language in which all the templates that generate the HTML UI of XWiki are written, it can be optionally activated in skin extensions, and it is executed when sending CSS and JavaScript skin resources from the filesystem.
47
48 In conclusion, **Velocity is suited for projects with small to medium complexity, and which don't require access to other resources except the provided XWiki API and registered script services. It allows very quick and easy development, offers good security and decent performance, and can easily be packaged and distributed as a XAR.**
49
50 == Groovy ==
51
52 Groovy is a full-fledged scripting language, which supports almost the entire Java syntax, and provides its own syntax delicacies and custom APIs that enhance the Java language even further. While it is recommended that complex code be written in Java as components accessible via script services, Groovy has the advantage that it is written live in the wiki, without requiring compilation, deployment and server restarts, thus enabling faster development.
53
54 The XWiki API is available in the context when executing Groovy scripts, but unlike in Velocity, the code isn't limited to this API, and any other classes or objects can be accessed freely. New classes can be defined in Groovy, compatible with Java classes, and this allows more structured code to be written, unlike in Velocity. A particular case of classes is new component roles and component implementations, which allows, for example, new script services or new event listeners to be defined in the wiki. It is possible to load attached jar files into the classpath of an executing script, which means that a wiki document can contain a complex program AND its required libraries not already provided by the platform.
55
56 Other than being available as a scripting language for writing custom code, it is also the language in which scheduler tasks are written.
57
58 In conclusion, **Groovy is suited for complex projects or for custom wiki enhancement through new components, when speedy live development is required. Being written in wiki documents, it can also be easily packaged and distributed as a XAR.**
59
60 After taking into account these considerations and if requiring Programming Rights isn't an issue for you, you should pick the script language that you're most familiar with!
61
62 = XWiki Scripting API =
63
64 The API is documented in Javadoc format and can be accessed here: [[XWiki API Javadoc>>DevGuide.API]]. If you are not familiar with Java or object oriented programming, you will probably be confused by the API documentation. It is not within the scope of our documentation to teach you all the details about Java, or object oriented programming. You can find all of that information already online. You can also explore the page code found throughout the [[Extensions wiki>>extensions:Main.WebHome]] area to see how others have figured out how to achieve a variety of results.
65
66 We're also making available an [[API Guide>>APIGuide]] with examples about using the XWiki API.
67
68 == [[Bindings>>extensions:Extension.Script Macro#HBindings]] ==
69
70 These main objects available to you in scripting languages are:
71
72 * The current Document: **##doc##**
73 * The Context of the request: **##xcontext##**
74 * The Request object: **##request##**
75 * The Response object: **##response##**
76 * The XWiki object: **##xwiki##**
77 * The XWiki utils: **##util##** (this is deprecated)
78 * Various [[Script Services>>extensions:Extension.Script Module]]: **##services##**
79
80 See [[Scripting Reference Documentation>>http://platform.xwiki.org/xwiki/bin/view/SRD/Navigation?xpage=embed]] for a complete list.
81
82 == [[XWiki Component>>extensions:Extension.Component Module]] Access ==
83
84 Since XWiki 4.1M2+ there's a Script Service to access the Component Manager (see also: [[Accessing components from Groovy>>DevGuide.WritingComponents#HFromwikipages]]).
85
86 For example using Groovy you'd write:
87
88 {{code language="java"}}
89 {{groovy}}
90 def greeter = services.component.getInstance(org.xwiki.component.HelloWorld.class)
91 println greeter.sayHello()
92 {{/groovy}}
93 {{/code}}
94
95 You can also get the ComponentManager with:
96
97 {{code language="java"}}
98 {{groovy}}
99 def cm = services.component.componentManager
100 {{/groovy}}
101 {{/code}}
102
103 {{info}}
104 With versions of XWiki older than 4.1M2 you'd use (in Groovy):
105
106 {{code language="java"}}
107 {{groovy}}
108 def greeter = com.xpn.xwiki.web.Utils.getComponent(org.xwiki.component.HelloWorld.class)
109 println greeter.sayHello()
110 {{/groovy}}
111 {{/code}}
112 {{/info}}
113
114 == XWiki Core Access ==
115
116 Sometimes the XWiki Api doesn't provide the methods which you need for your application. You can gain raw access the core of XWiki but it presents an increased security risk and requires **Programming Rights** to be able to save the page containing the script (Programming Rights are not required for viewing a page containing a script requiring Programming Rights, rights are only needed at save time). Using the core should be avoided if at all possible.
117
118 {{code language="java"}}
119 {{groovy}}
120 def xc = xcontext.getContext();
121 def wiki = xc.getWiki();
122 def xdoc = doc.getDocument();
123 {{/groovy}}
124 {{/code}}
125
126 After using this snippet, you will have 3 new objects:
127
128 * [[The underlying XWikiContext behind the Context object>>http://maven.xwiki.org/site/xwiki-core-parent/xwiki-core/apidocs/com/xpn/xwiki/XWikiContext.html]]: **##xc##**
129 * [[The underlying XWiki object which backs the **##xwiki##** object>>http://maven.xwiki.org/site/xwiki-core-parent/xwiki-core/apidocs/com/xpn/xwiki/XWiki.html]]: **##wiki##**
130 * [[The underlying XWikiDocument behind the current Document>>http://maven.xwiki.org/site/xwiki-core-parent/xwiki-core/apidocs/com/xpn/xwiki/doc/XWikiDocument.html]]: **##xdoc##**
131
132 You will find that many of the methods in **##wiki##** and **##xdoc##** require an instance of the XWikiContext, this is the underlying xcontext **##xc##** not the Api context **##xcontext##**.
133
134 Again, these methods are only for the rare cases when functionality is not provided by the public Api. We put a lot of effort into preserving the behavior of the public Api and much less into preserving the behavior of core methods so you may find that core methods are deprecated, removed, or their behavior is changed in subsequent versions.
135
136 == Querying XWiki's Model ==
137
138 From your script you can query the full XWiki Model. Check the [[Query Module>>extensions:Extension.Query Module]] for more information.
139
140 {{id name="velocity"/}}
141
142 = Velocity Specific Information =
143
144 Velocity is currently the only scripting language which can be used without Programming [[AdminGuide.Access Rights]]. This means you can save velocity scripts using a user with less permission and an exploit of your script is less of a security breach.
145
146 You can [[gain access to the XWiki core>>#HXWikiCoreAccess]] from Velocity but this will require Programming Rights. Strictly speaking, protected APIs are only available when the page that contains them was last saved by someone who had Programming Rights (see above).
147
148 In Velocity you can't import classes and as such you cannot gain direct access to XWiki components as shown [[above>>#HXWikiComponentAccess]]. This leaves you with the provided [[bindings>>#HBindings]] (NOTE: In Velocity, these bindings all start with **##$##** as with all other Velocity variables)
149
150 For more information about programming in the Velocity language, you can refer to the [[Velocity User Guide>>http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html]].
151
152 For more details on using Velocity check the [[Velocity Module Documentation>>extensions:Extension.Velocity Module]] which also contains the full list of Velocity Tools that you can use in your scripts.
153
154 {{info}}
155 If you wish to add new Velocity tools you'll need to edit your ##xwiki.properties## file and follow the instructions in there.
156 {{/info}}
157
158 To include Velocity scripts in other Velocity scripts, see [[How to include a velocity page into another page>>DevGuide.IncludeInVelocity]].
159
160 == Other Velocity Variables ==
161
162 {{warning}}
163 These variables can be used but are subject to change in the future.
164 {{/warning}}
165
166 === Controlling Which Sections to Display ===
167
168 You can control whether to display Comments/History/Attachment/Information sections or not by setting some velocity variables to ##false##:
169
170 {{code language="velocity"}}
171 #set ($showcomments = false)
172 #set ($showattachments = false)
173 #set ($showhistory = false)
174 #set ($showinformation = false)
175 {{/code}}
176
177 To remove them all you can set:
178
179 {{code language="velocity"}}
180 #set($docextras = [])
181 {{/code}}
182
183 === Information about the current user ===
184
185 The following variables (set in the {{scm path="xwiki-platform-core/xwiki-platform-web/src/main/webapp/templates/xwikivars.vm"}}xwikivars.vm{{/scm}} template) are shortcuts for checking various information **for the current user**:
186
187 * ##$isGuest##: checks if the current user is ##XWiki.XWikiGuest##
188 * ##$isSuperAdmin##: checks if the current user is the special user ##superadmin##
189
190 * ##$hasComment##: checks comment rights on the current document
191 * ##$hasEdit##: checks edit rights on the current document
192 * ##$hasWatch##: checks if the user is authenticated and the watch service is available
193
194 * ##$hasAdmin##: checks admin rights on the current document
195 * ##$hasSpaceAdmin##: checks admin rights on the ##XWikiPreferences## document of the current space
196 * ##$hasGlobalAdmin##: checks admin rights on ##XWiki.XWikiPreferences##
197
198 * ##$hasCreateSpace##: checks edit rights on that page that does not exist, in a space that doesn't exist
199 * ##$hasCreatePage##: checks edit rights on that page that does not exist, in the current space
200
201 * ##$hasProgramming##: checks if the current user has programming rights
202
203 * ##$isAdvancedUser##: advanced users: ##superadmin##, users with the ##usertype## property set to "Advanced", guest users with admin rights
204
205 Example:
206
207 {{code language="velocity"}}
208 {{velocity}}
209 #if ($hasAdmin)
210 ## This link will only be visible to users that have admin rights on this document
211 [[Do some admin action>>Some.Document]]
212 #end
213 {{/velocity}}
214 {{/code}}
215
216 === Information about the current wiki ===
217
218 The following variables (set in the {{scm path="xwiki-platform-core/xwiki-platform-web/src/main/webapp/templates/xwikivars.vm"}}xwikivars.vm{{/scm}} template) are shortcuts for checking various information **about the current wiki**:
219
220 * ##$isReadOnly##
221 * ##$isInServletMode##
222 * ##$isInPortletMode##
223
224 = Groovy Specific Information =
225
226 {{info}}
227 Currently all non Velocity scripting languages are only allowed to be used by users having Programming Rights.
228 {{/info}}
229
230 * See Groovy snippets in the [[Extensions wiki>>extensions:Main.WebHome]] (click on the "Groovy" tag in the Tag Cloud)
231 * [[Groovy web site>>http://groovy.codehaus.org/]]
232
233 == Groovy Example ==
234
235 The following example demonstrates how to use a groovy script to interact with velocity code in your page. This example performs a DNS lookup from the velocity variable ##$hostname## and stores the result in the variable ##$address##.
236
237 **Using XWiki Syntax 2.0:**
238
239 Objects can be passed back and forth between scripting languages by storing them in commonly available objects. One such commonly available object which only lasts the length of the request is the context object, known as xcontext.
240
241 {{code language="velocity"}}
242 {{velocity}}
243 #set($hostname = "www.xwiki.org")
244 Host Name: $hostname
245 $xcontext.put("hostname", $hostname)
246 {{/velocity}}
247 {{groovy}}
248 import java.net.InetAddress;
249 host = xcontext.get("hostname");
250 InetAddress addr = InetAddress.getByName(host);
251 String address = addr.getHostAddress();
252 xcontext.put("address", address);
253 {{/groovy}}
254 {{velocity}}
255 IP Address: $xcontext.get("address")
256 {{/velocity}}
257 {{/code}}
258
259 **Using XWiki Syntax 1.0:**
260
261 Because Groovy and Velocity code are parsed together, variables defined in Groovy can be used directly in velocity without storing in and retrieving from the context.
262
263 {{code language="velocity"}}
264 #set ($hostname = "www.xwiki.org")
265 Host Name: $hostname
266 <%
267 import java.net.InetAddress;
268 vcontext = context.get("vcontext");
269 host = vcontext.get("hostname");
270 InetAddress addr = InetAddress.getByName(host);
271 String address = addr.getHostAddress();
272 %>
273 IP Address: $address
274 {{/code}}
275
276 = Python Specific Information =
277
278 You can run Python code in XWiki just like Velocity or Groovy.
279
280 {{code language="python"}}
281 {{python}}
282 print "The full name of this document is " + doc.getFullName()
283 {{/python}}
284 {{/code}}
285
286 = Share variable between languages =
287
288 Most JSR223 based scripting languages reinject the created variable in the current ##ScriptContext## which means you can define a variable in a Groovy script and reuse it in a following Python script for example.
289
290 Since 4.1M2 a bridge has been written for Velocity (which is not based on JSR223) to allow it to access the current ScriptContext variable so you can do things like:
291
292 {{code}}
293 {{groovy}}
294 var = "toto"
295 {{/groovy}}
296
297 {{velocity}}
298 $var
299 {{/velocity}}
300 {{/code}}
301
302 Note that you can also share variables by setting them in the XWiki Context (##xcontext## binding).
303
304 = Scripting In XWiki Syntax 1.0 =
305
306 XWiki Syntax 1.0 is rendered by an old rendering engine which is still supported but for which no further development is planned (it will eventually be removed). Syntax 1.0 has some idiosyncrasies which were solved by syntax 2.0.
307
308 * The only scripting languages available to you are Velocity and Groovy.
309 * In Groovy, the context is known as: **##context##** not **##xcontext##**
310 * The beginning and end of Groovy scripts are denoted by <% and %> rather than through the [[extensions:Extension.Groovy Macro]] (using ~{~{groovy}} and ~{~{/groovy}})
311 * Velocity is parsed in a page no matter what (there is no need to invoke the [[extensions:Extension.Velocity Macro]] using ~{~{velocity}} and ~{~{/velocity}})
312
313 The last part is important because it means you need to be careful when using **$** and **#** in your document. This is still true inside of **<%** and **%>** so you have to be careful when writing Groovy.

Get Connected