Wiki source code of XWiki Velocity Training

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

Get Connected