Wiki source code of XWiki Velocity Training

Version 35.1 by bprieur on 2015/06/09

Show last authors
1 = How to use Velocity in XWiki pages =
2 by Guillaume Delhumeau
3 July 2013
4
5
6 == What is it? ==
7
8 === ===
9
10 * Velocity is a **template** language.
11 * It describes what your page should be.
12 ** Which means it **control** what you **display**.
13
14 Examples:
15 * display the name of the user
16 * display an image under certain circonstances only
17 * display a list of all the blog categories
18
19 === Example ===
20 {{code language="velocity"}}
21 {{velocity}}
22 Welcome $xcontext.user !
23 #if($hasAdmin)
24 You will see the following picture because you are an administrator:
25 image:picture.jpg
26 #end
27 {{/velocity}}
28 {{/code}}
29
30 Will output:
31 {{image reference="sample1.png" /}}
32
33 === ===
34 * With XWiki and Velocity, you can retrieve informations contained in other pages
35
36 {{code language="velocity"}}
37 #set($docRef = $services.model.createDocumentReference('', 'OtherSpace', 'OtherPage'))
38 #set($document = $xwiki.getDocument($docRef))
39 The content of the other document is:
40 $document.getContent()
41 {{/code}}
42
43
44 {{image reference="serrure.jpg"/}}
45
46 === ===
47
48 * or do advanced searches throught the wiki (via the //Query Module//) :
49 ** //« give me all the blog entries posted during the month of july 2012 and that are not archived and that have at least 3 comments and... »//
50
51 {{image reference="detective.jpg"/}}
52
53 === ===
54 * But XWiki also allows you to use Velocity to **save** things in the wiki.
55
56 {{code language="velocity"}}
57 #set($object = $doc.getObject('XWiki.XWikiUsers'))
58 $object.set('first_name', 'Nobody')
59 $doc.save()
60 {{/code}}
61
62
63 {{image reference="nobody.jpg"/}}
64
65 == Principles ==
66
67 === Lines ===
68 * A line begining by '#' is a Velocity instruction
69 * All other lines are normal lines
70
71 {{code language="velocity"}}
72 ## This is a velocity comment - a comment is never displayed and is used to
73 ## add useful information inside a source code.
74 #set($myVar = 42)
75 ## The line above was a velocity instruction
76 This line is a normal line
77 {{/code}}
78
79 === Variables ===
80 * A //variable// is like a box that can contains data: text, numbers, objects, etc...
81 * A variable is always prefixed by a dollar '$'.
82 * To create a variable, just use the //#set()// Velocity instruction
83
84 {{code language="velocity"}}
85 #set($myVar = 42)
86 {{/code}}
87
88 * If a variable is inside a normal line, the content of the variable will be displayed:
89
90 {{code language="velocity"}}
91 #set($myVar = 42)
92 I am $myVar years old.
93 {{/code}}
94
95 will display:
96
97 {{image reference="variables.png"/}}
98
99 === ===
100 Some variables are already created by XWiki when you write a Velocity code, and you can use them.
101
102
103 This is some of them:
104 * //$hasEdit// : this variable tells us if the current user has the edit rights on the current page
105 * //$isGuest// : this variable tells us if the current user is a guest
106 * //$doc// : this variable represents the current document.
107 * //$xwiki// : this special variable is a tool to perform complicated stuffs
108 * //$request// : gives a lot of informations about the current request (like the referer, the query string, etc...)
109
110 === Methods ===
111 * Some variable are //objects//. An object can contains //variables// and //methods//.
112 * A method is like an //action// that the object can perform.
113 * Some actions give you an information, some just perform something.
114 * To call them, you write //$someObject.someMethod()// - with the '()'.
115
116 Examples:
117
118 {{code language="velocity"}}
119 ## will save the current document:
120 $doc.save()
121 ## will give you the content of the document:
122 $doc.getContent()
123 ## this method takes a "parameter", a text, which will be the new title:
124 $doc.setTitle("My new title")
125 ## will give you the current skin
126 $xwiki.getSkin()
127 {{/code}}
128
129 === Class ===
130
131 * Every object is different, they don't have the same variables and methods.
132 * But every object is an //instance// of a //class//.
133 * A //class// is like a model that describes what the object will have.
134 ** For example, the //Document// class has a //save// method, so every objects that are //instances// of //Document// will have the //save// method.
135 ** The //String// class has a //length// variable, so every instances of //String// will have this variable too.
136
137 === ===
138 * You can use the following code to know what is the class of an object:
139
140 {{code language="velocity"}}
141 #set($myVar = 42)
142 $myVar.class.name ## will display 'java.lang.Integer'
143 #set($myVar2 = "This is a text")
144 $myVar2.class.name ## will display 'java.lang.String'
145 $doc.class.name ## will display 'com.xpn.xwiki.api.Document'
146 $xwiki.class.name ## will display 'com.xpn.xwiki.api.XWiki'
147 {{/code}}
148
149
150 {{image reference="class.jpg"/}}
151
152 === ===
153 * Now that you know the class of your object, you can google it to have its documentation!
154 * With this documentation, you will be able to knows what method you can use.
155 ** Example with //java.lang.String//
156
157 {{image reference="javadoc.png"/}}
158
159 === ===
160 * As you may have notice, the classes come from the //Java// world.
161 * The documentation about the java classes is called //Javadoc//.
162 * So you can use the the //Javadoc// for Velocity too!
163
164
165
166 {{image reference="java.jpg"/}}
167
168 == Basic instructions ==
169 === Conditions ===
170 * When you want to display something only under certain circounstances, you can use the //#if// command.
171
172 {{code language="velocity"}}
173 #if($isGuest)
174 Welcome visitor! You should subscribe to the wiki !
175 #end
176 {{/code}}
177
178 * You can also use the //#else// command:
179
180 {{code language="velocity"}}
181 #if($isGuest)
182 Welcome visitor! You should subscribe to the wiki !
183 #else
184 Hello $xcontext.user! I'm happy to see a registred user, I hate visitors!
185 #end
186 {{/code}}
187
188
189 {{image reference="visitors.jpg"/}}
190
191 === Conditions (bis) ===
192 * You can compare variables, with the following operators:
193 ** **//==//** : compare if the variables are equals
194 ** **//!=//** : say if the variables are differents
195 ** **//>//** : say if the variable is superior to the other
196 ** **//<//** : do the oposite
197 ** **//>=//** : say if the variable is superior or equal to the other
198 ** **//<=//** : say if the variable is inferior or equal to the other
199
200 * You can create complicated conditions, with the logic operators:
201 ** **//&&//** : which means **"AND"**.
202 ** **//||//** : which means **"OR"**.
203 ** **//!//** : which means **"NOT"**.
204
205 === Examples ===
206 {{code language="velocity"}}
207 #set($a = 12)
208 #set($b = 28)
209
210 #if($a < $b)
211 A is inferior
212 #else
213 B is inferior
214 #end
215
216 #if($a < 20 && $b > 17)
217 A is inferior than 20 AND B is superior than 17
218 #end
219
220 #if($a == 15 || $b <= 2)
221 A equals 15 OR B is inferior than 2 or equal
222 #end
223 {{/code}}
224
225 === Examples (bis) ===
226 {{code language="velocity"}}
227 #set($c = true)
228
229 #if($c)
230 C is true
231 #end
232
233 #if($doc.isNew())
234 The document is New
235 #else
236 The document is an old document
237 #end
238
239 #if(!$doc.isHidden())
240 The document is NOT hidden
241 #end
242 {{/code}}
243
244 === Lists ===
245 * You can create a list of objects.
246
247 {{code language="velocity"}}
248 #set($myList = ['My first Item', 'My Second Item', 'My third item'])
249 {{/code}}
250
251 * You can add a new element in the list:
252
253 {{code language="velocity"}}
254 $myList.add('My fourth item')
255 {{/code}}
256
257 * You can know how many objects are inside the list:
258
259 {{code language="velocity"}}
260 $myList.size()
261 {{/code}}
262
263 * You can ask if an object is inside the list
264
265 {{code language="velocity"}}
266 $myList.contains('My Second Item') ## which tells me 'true' or 'false'
267 {{/code}}
268
269 === Example of lists ===
270 {{code language="velocity"}}
271 $doc.getComments() ## will give all the comments of the current page !
272 $doc.getAttachmentList() ## will give all the attachments of the current page
273 $xwiki.getSpaces() ## will give the list of the different spaces of the wiki
274 {{/code}}
275
276
277 How could I know the number of spaces in the wiki?
278
279 {{code language="velocity"}}
280 ...
281 {{/code}}
282
283
284 How could I know if the space 'BlaBla' exists?
285
286 {{code language="velocity"}}
287 ...
288 {{/code}}
289
290
291 {{image reference="teacher.jpg"/}}
292
293 === Example of lists ===
294 {{code language="velocity"}}
295 $doc.getComments() ## will give all the comments of the current page !
296 $doc.getAttachmentList() ## will give all the attachments of the current page
297 $xwiki.getSpaces() ## will give the list of the different spaces of the wiki
298 {{/code}}
299
300
301 How could I know the number of spaces in the wiki?
302
303 {{code language="velocity"}}
304 $xwiki.getSpaces().size()
305 {{/code}}
306
307
308 How could I know if the space 'BlaBla' exists?
309
310 {{code language="velocity"}}
311 $xwiki.getSpaces().contains('BlaBla')
312 {{/code}}
313
314
315 {{image reference="goodmark.jpg"/}}
316
317 === Foreach ===
318 * How can I display all the elements of a list in a nice way?
319 ** Use the //#foreach// loop, son.
320 * Example:
321
322 {{code language="velocity"}}
323 This is the list of all the spaces of the wiki
324 #set($spaceList = $xwiki.getSpaces())
325 #foreach($space in $spaceList)
326 * $space
327 #end
328 {{/code}}
329
330 * Results:
331 {{image reference="foreach1.png"/}}
332
333 == The API ==
334
335 === ===
336 * XWiki offers a lot of objects with a lot of methods, to perform a lot of things !
337 ** Delete a document, add a tag to an other document, display the list of all blog entries, handle complex formulars, etc...
338 * This objets & methods are called the **API** (as //Application Programming Interface//).
339 * But how can I know what are theses objects and how to use it?
340
341 {{image reference="API.jpg"/}}
342
343 === By using the XWiki Script Reference Documentation (SRD) ===
344
345 {{image reference="SRD.png"/}}
346
347 http://platform.xwiki.org/xwiki/bin/view/SRD/Navigation?xpage=embed
348
349 === SRD ===
350 * The left column lists **all the XWiki special variables that make the API**.
351 * Select one of them, and you will have **all the methods this special variable offers**
352 ** Examples:
353 *** //$xwiki// offers a method //getDocument()//
354 *** //$doc// has a method //addAttachment()//
355 *** etc...
356
357 === Is the API a mess?===
358 * While looking at the SRD, we can ask youself //"how many special variables is there?"//
359 * When we create a variable for our own usage, we have to be sure first to not call it as an existing special variable.
360 ** It's a mess!!!
361
362 {{image reference="mess.jpg"/}}
363
364 === Introducing Script Services ===
365 * In order to make the things cleaner, the plan is to remove a lot of this special variables and replace them by //script services//.
366 * Script services will become the only API in future.
367 * All script services are prefixed by //$services//.
368
369 {{image reference="datacenter.jpg"/}}
370
371 === ===
372 * To use a script service, you do it this way:
373
374 {{code language="velocity"}}
375 $services.query ## to perform complicated researchs
376 $services.localization ## to take care of the languages
377 $services.officeimporter ## to import office documents
378 ...
379 {{/code}}
380
381 * Of course, it is documented on the SRD!
382
383 {{image reference="wayne.jpg"/}}
384
385 === ===
386 * Sometime, you have different ways to do the same thing:
387 ** Using an old method (which may be declared as //deprecated//).
388 ** Using a script service instead
389 * ** Always perfers to use Script Service instead of deprecated APIs!!!**
390
391 {{code language="velocity"}}
392 $xwiki.searchDocument() ## allow us to perfom a query with the HQL language
393 ## now please use:
394 $services.query.hql() ## allow us to perfom a query with the HQL language
395 ## or even better:
396 $services.query.xwql() ## XWQL language is easier to use
397 {{/code}}
398
399 * Because it's the future!
400
401 {{image reference="future.jpg"/}}
402
403 == Manipulation of XObjects ==
404 === What is an XObject ? ===
405 * An //XObject// is an **object** that you can **save** in the wiki.
406 * An XObject is attached on a document, and you can see them with the "objects editor" on the wiki.
407
408 {{image reference="edit_objects.png"/}}
409
410 === ===
411 {{image reference="objects.png"/}}
412
413 === XClass ===
414 * An //XClass// is a //class// (a //description//) for XObjects.
415 ** You can define them using the class editor.
416 ** Or by using //Application Within Minutes//!
417
418 === Class Editor ===
419 {{image reference="class_editor.png"/}}
420
421 === Application Within Minutes ===
422 {{image reference="appwithinminutes.png"/}}
423
424 === Why using XClass and XObjects? ===
425 * It allows us to store **structured** informations.
426 ** A //Blog Post// (with a //title//, a //date//, a //content//, etc...)
427 ** An //Evaluation document// (with a //remark// for each //category//, a //mark//, etc...)
428 ** An //Holiday Request// (with //dates//, //status//, etc...)
429
430 * So the //information// is not lost in a giant document that holds only a big text...
431 ** And you can create //Applications//!
432
433 === XClass is used //everywhere// ===
434 * Almost everything in XWiki is an XClass and stored as XObjects!
435 ** //Users//
436 ** //Groups//
437 ** //Comments//
438 ** //Tags//
439 ** //Access Rights//
440 ** ....
441 * Learn to use //XClass// and you can **control all your wiki**.
442
443 === A comment is an XObject ===
444 {{image reference="comments.png"/}}
445
446 === A user is an XObject ===
447 {{image reference="user.png"/}}
448
449 === How to get an XObject with Velocity? ===
450
451 {{code language="velocity"}}
452 ## First, get the object
453 #set($object = $doc.getObject('XWiki.XWikiUsers'))
454 ## The parameter is the name of the class of the object you want to have
455 ## (a document can hold multiple objects of different classes)
456 ## The class name is the Document name where the class is defined
457
458 ## Display a parameter:
459 $object.display('first_name', 'view')
460 ## the parameter is the name of the field you want to display
461 ## if you are in "edit" mode, an HTML field will be displayed instead of the object value.
462
463 ## Set values:
464 $object.set('last_name', 'Bond')
465 $object.set('first_name', 'James')
466
467 ## Then save the document if you want your changes to be conserved
468 ## (you can add a comment when you save)
469 $doc.save('I have changed the name of the user.')
470 {{/code}}
471
472 === You can rollback what your script have done ===
473 {{image reference="rollback.png"/}}
474
475 == Tips ==
476
477 === How to get an other document? ===
478 * In the past, we used to do:
479
480 {{code language="velocity"}}
481 #set($document = $xwiki.getDocument('Space.Page'))
482 {{/code}}
483
484 * But it's not good, because what if the page name has a dot?
485
486 {{code language="velocity"}}
487 #set($document = $xwiki.getDocument('Space.Pa.ge'))
488 ## ??? What is the Space ? What is the Page ?
489 {{/code}}
490
491 * And what will happen if the document name have accents or weird characters?
492
493 === Solution: use references !===
494
495 {{code language="velocity"}}
496 #set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Page'))
497 #set($document = $xwiki.getDocument($reference))
498 {{/code}}
499
500 * It is better! The reference tool allow us to strictly separe what is the space and what is the page
501 * And the reference tool will take care of weird characters !
502
503 {{code language="velocity"}}
504 #set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Pa.ge'))
505 #set($document = $xwiki.getDocument($reference))
506 ## Not a problem!!!
507 {{/code}}
508
509 === References ===
510 * You can get create references for documents in other wikis :
511
512 {{code language="velocity"}}
513 #set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Page'))
514 {{/code}}
515
516 * If you want to get a document in the current wiki, you can set an empty parameter:
517
518 {{code language="velocity"}}
519 #set($reference = $services.model.createDocumentReference('', 'Space', 'Page'))
520 ## the reference point a document in the current wiki
521 {{/code}}
522
523 === Use case: changing the name of a user ===
524
525 {{code language="velocity"}}
526 ## First, create a reference to his user page
527 #set($reference = $services.model.createDocumentReference('', 'XWiki', 'ldubost'))
528 ## Then, get its document
529 #set($document = $xwiki.getDocument($reference))
530 ## Then, get the 'User' object
531 #set($object = $document.getObject('XWiki.XWikiUsers'))
532 ## Then change his name
533 $object.set('first_name', 'Harry')
534 $object.set('last_name', 'Potter')
535 ## And save the document
536 $document.save()
537 {{/code}}
538
539 === But remember we know who changes what! ===
540 {{image reference="history.png"/}}
541
542 (% style="text-align: right; margin-top: 20px;" %)
543 "//I have your name and I know where you live...//"
544
545 == Going further ==
546 === ===
547 * See the [[Velocity documentation>>http://velocity.apache.org/]] to have more details about the language itself
548 * See the [[XWiki Script Guide>>http://platform.xwiki.org/xwiki/bin/view/DevGuide/Scripting]] to have some informations about how to make scripts in XWiki
549 * See the [[XWiki Query Module>>http://extensions.xwiki.org/xwiki/bin/view/Extension/Query+Module]] to learn how to do advanced queries
550 * See the [[XWiki Data Model>>http://platform.xwiki.org/xwiki/bin/view/DevGuide/DataModel]] to learn how to create your XWiki classes
551
552 **But in general:**
553 * practice and ask for help!!!
554
555 === ===
556 * I hope you now have a better idea of what Velocity is and how you can use it in XWiki.
557
558 {{image reference="velocity.jpg"/}}

Get Connected