Velocity Training

Last modified by Simpel on 2024/01/03

How to use Velocity in XWiki pages

What is it?

  • Velocity is a template language.
  • It describes what your page should be.
    • Which means it controls what you display.

Examples:

  • display the name of the user
  • display an image under certain circonstances only
  • display a list of all the blog categories

Example

{{velocity}}
Welcome $xcontext.user !
#if($hasAdmin)
  You will see the following picture because you are an administrator:
  image:picture.jpg
#end
{{/velocity}}

Will output:
sample1.png

  • With XWiki and Velocity, you can retrieve informations contained in other pages
#set($docRef   = $services.model.createDocumentReference('', 'OtherSpace', 'OtherPage'))
#set($document = $xwiki.getDocument($docRef))
The content of the other document is:
$document.getContent()

serrure.jpg

  • or do advanced searches throught the wiki (via the Query Module) :
    • « 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... » 

detective.jpg

  • But XWiki also allows you to use Velocity to save things in the wiki.
#set($object = $doc.getObject('XWiki.XWikiUsers'))
$object.set('first_name', 'Nobody')
$doc.save()

nobody.jpg

Principles

Lines

  • A line begining by '#' is a Velocity instruction
  • All other lines are normal lines
## This is a velocity comment - a comment is never displayed and is used to
## add useful information inside a source code.
#set($myVar = 42)
## The line above was a velocity instruction
This line is a normal line

Variables

  • A variable is like a box that can contain data: text, numbers, objects, etc...
  • A variable is always prefixed by a dollar '$'.
  • To create a variable, just use the #set() Velocity instruction
#set($myVar = 42)
  • If a variable is inside a normal line, the content of the variable will be displayed:
#set($myVar = 42)
I am $myVar years old.

will display:

variables.png

Some variables are already created by XWiki when you write a Velocity code, and you can use them.

This is some of them:

  • $hasEdit : this variable tells us if the current user has the edit rights on the current page
  • $isGuest : this variable tells us if the current user is a guest
  • $doc : this variable represents the current document.
  • $xwiki : this special variable is a tool to perform complicated stuffs
  • $request : gives a lot of informations about the current request (like the referer, the query string, etc...)

Methods

  • Some variable are objects. An object can contain variables and methods.
  • A method is like an action that the object can perform.
  • Some actions give you an information, some just perform something.
  • To call them, you write $someObject.someMethod() - with the '()'.

Examples:

## will save the current document:
$doc.save()
## will give you the content of the document:
$doc.getContent()
## this method takes a "parameter", a text, which will be the new title:
$doc.setTitle("My new title")
## will give you the current skin
$xwiki.getSkin()

Class

  • Every object is different, they don't have the same variables and methods.
  • But every object is an instance of a class.
  • A class is like a model that describes what the object will have.
    • For example, the Document class has a save method, so every objects that are instances of Document will have the save method.
    • The String class has a length variable, so every instances of String will have this variable too.

  • You can use the following code to know what is the class of an object:
#set($myVar = 42)
$myVar.class.name  ## will display 'java.lang.Integer'
#set($myVar2 = "This is a text")
$myVar2.class.name ## will display 'java.lang.String'
$doc.class.name    ## will display 'com.xpn.xwiki.api.Document'
$xwiki.class.name  ## will display 'com.xpn.xwiki.api.XWiki'

class.jpg

  • Now that you know the class of your object, you can google it to have its documentation!
  • With this documentation, you will be able to knows what method you can use.
    • Example with java.lang.String

javadoc.png

  • As you may have noticed, the classes come from the Java world.
  • The documentation about the java classes is called Javadoc.
  • So you can use the the Javadoc for Velocity too!

java.jpg

Basic instructions

Conditions

  • When you want to display something only under certain circumstances, you can use the #if command.
#if($isGuest)
  Welcome visitor! You should subscribe to the wiki !
#end
  • You can also use the #else command:
#if($isGuest)
  Welcome visitor! You should subscribe to the wiki !
#else
  Hello $xcontext.user! I'm happy to see a registred user, I hate visitors!
#end

visitors.jpg

Conditions (bis)

  • You can compare variables, with the following operators:
    • == : compare if the variables are equal
    • != : say if the variables are different
    • >  : say if the variable is superior to the other
    • <  : do the oposite
    • >= : say if the variable is superior or equal to the other
    • <= : say if the variable is inferior or equal to the other
  • You can create complicated conditions, with the logic operators:
    • && : which means "AND".
    • || : which means "OR".
    • ! : which means "NOT".

Examples

#set($a = 12)
#set($b = 28)

#if($a < $b)
  A is inferior
#else
  B is inferior
#end

#if($a < 20 && $b > 17)
  A is inferior than 20 AND B is superior than 17
#end

#if($a == 15 || $b <= 2)
  A equals 15 OR B is inferior than 2 or equal
#end

Examples (continued)

#set($c = true)

#if($c)
  C is true
#end

#if($doc.isNew())
  The document is New
#else
  The document is an old document
#end

#if(!$doc.isHidden())
  The document is NOT hidden
#end

Lists

  • You can create a list of objects.
#set($myList = ['My first Item', 'My Second Item', 'My third item'])
  • You can add a new element in the list:
$myList.add('My fourth item')
  • You can know how many objects are inside the list:
$myList.size()
  • You can ask if an object is inside the list
$myList.contains('My Second Item') ## which tells me 'true' or 'false'

teacher.jpg

Example of lists

$doc.getComments() ## will give all the comments of the current page !
$doc.getAttachmentList() ## will give all the attachments of the current page
$xwiki.getSpaces() ## will give the list of the different spaces of the wiki

How could I know the number of spaces in the wiki?

$xwiki.getSpaces().size()

How could I know if the space 'BlaBla' exists?

$xwiki.getSpaces().contains('BlaBla')

goodmark.jpg

Foreach

  • How can I display all the elements of a list in a nice way?
    • Use the #foreach loop, son.
  • Example:
This is the list of all the spaces of the wiki
#set($spaceList = $xwiki.getSpaces())
#foreach($space in $spaceList)
  * $space
#end
  • Results:
    foreach1.png

The API

  • XWiki offers a lot of objects with a lot of methods, to perform a lot of things !
    • Delete a document, add a tag to another document, display the list of all blog entries, handle complex formulars, etc...
  • This objects & methods are called the API (as Application Programming Interface).
  • But how can I know what are theses objects and how to use it?

API.jpg

By using the XWiki Script Reference Documentation (SRD)

SRD.png

Go to the SRD.

SRD

  • The left column lists all the XWiki special variables that make the API.
  • Select one of them, and you will have all the methods this special variable offers
    • Examples:
      • $xwiki offers a method getDocument()
      • $doc has a method addAttachment()
      • etc...

Is the API a mess?

  • While looking at the SRD, we can ask youself "how many special variables are there?"
  • When we create a variable for our own usage, we have to be sure first to not call it as an existing special variable.
    • It's a mess!!!

mess.jpg

Introducing Script Services

  • In order to make the things cleaner, the plan is to remove a lot of this special variables and replace them by script services.
  • Script services will become the only API in future.
  • All script services are prefixed by $services.

datacenter.jpg

  • To use a script service, you do it this way:
$services.query ## to perform complicated researchs
$services.localization ## to take care of the languages
$services.officeimporter ## to import office documents
...
  • Of course, it is documented on the SRD!

wayne.jpg

  • Sometime, you have different ways to do the same thing:
    • Using an old method (which may be declared as deprecated).
    • Using a script service instead
  •  Always perfers to use Script Service instead of deprecated APIs!!!
$xwiki.searchDocument() ## allow us to perfom a query with the HQL language
## now please use:
$services.query.hql()   ## allow us to perfom a query with the HQL language
## or even better:
$services.query.xwql()  ## XWQL language is easier to use
  • Because it's the future!

future.jpg

Manipulation of XObjects

What is an XObject ?

  • An XObject is an object that you can save in the wiki.
  • An XObject is attached to a document, and you can see them with the "objects editor" on the wiki.

edit_objects.png

objects.png

XClass

  • An XClass is a class (a description) for XObjects.
    • You can define them using the class editor.
    • Or by using Application Within Minutes!

Class Editor

class_editor.png

Application Within Minutes

appwithinminutes.png

Why using XClass and XObjects?

  • It allows us to store structured informations.
    • A Blog Post (with a title, a date, a content, etc...)
    • An Evaluation document (with a remark for each category, a mark, etc...)
    • An Holiday Request (with dates, status, etc...)
  • So the information is not lost in a giant document that holds only a big text...
    • And you can create Applications!

XClass is used everywhere

  • Almost everything in XWiki is an XClass and stored as XObjects!
    • Users
    • Groups
    • Comments
    • Tags
    • Access Rights
    • ....
  • Learn to use XClass and you can control all your wiki.

A comment is an XObject

comments.png

A user is an XObject

user.png

How to get an XObject with Velocity?

## First, get the object
#set($object = $doc.getObject('XWiki.XWikiUsers'))
## The parameter is the name of the class of the object you want to have
## (a document can hold multiple objects of different classes)
## The class name is the Document name where the class is defined

## Display a parameter:
$object.get('first_name')
## the parameter is the name of the field you want to display
## if you are in "edit" mode, an HTML field will be displayed instead of the object value.

## Set values:
$object.set('last_name', 'Bond')
$object.set('first_name', 'James')

## Then save the document if you want your changes to be conserved
## (you can add a comment when you save)
$doc.save('I have changed the name of the user.')

You can rollback what your script has done

rollback.png

Tips

How to get a document?

  • In the past, we used to do:
#set($document = $xwiki.getDocument('Space.Page'))
  • But it's not good, because what if the page name has a dot?
#set($document = $xwiki.getDocument('Space.Pa.ge'))
## ??? What is the Space ? What is the Page ?
  • And what will happen if the document name have accents or weird characters?

Solution: use references !

#set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Page'))
#set($document  = $xwiki.getDocument($reference))
  • It is better! The reference tool allow us to strictly separate what is the space and what is the page
  • And the reference tool will take care of weird characters !
#set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Pa.ge'))
#set($document  = $xwiki.getDocument($reference))
## Not a problem!!!

References

  • You can get create references for documents in other wikis :
#set($reference = $services.model.createDocumentReference('Wiki', 'Space', 'Page'))
  • If you want to get a document in the current wiki, you can set an empty parameter:
#set($reference = $services.model.createDocumentReference('', 'Space', 'Page'))
## the reference point to a document in the current wiki

Use case: changing the name of a user

## First, create a reference to their user page
#set($reference = $services.model.createDocumentReference('', 'XWiki', 'ldubost'))
## Then, get its document
#set($document  = $xwiki.getDocument($reference))
## Then, get the 'User' object
#set($object    = $document.getObject('XWiki.XWikiUsers'))
## Then change their name
$object.set('first_name', 'Harry')
$object.set('last_name', 'Potter')
## And save the document
$document.save()

But remember we know who changes what!

history.png

"I have your name and I know where you live..."

Going further

But in general:

  • practice and ask for help!!!

  • I hope you now have a better idea of what Velocity is and how you can use it in XWiki.

velocity.jpg

Get Connected