Scripting API Guide
- Snippets
- Querying documents
- Create a new Document
- Accessing the request
- Getting external content
- Add objects to a page
- Access objects in a page
- Access objects from any page and loop over all objects of same Class
- Include a Velocity page into another Velocity page
- Redirecting to another page
- Add an Attachment to a page
- Add a new user to a List of Users xobject
- Create an XClass
- Modify the last update date
- Find XDOM Blocks
- Mark a page as hidden
- List all attachments of a page
This guide covers the main XWiki APIs that you can use from scripts in wiki pages. It's not meant to be comprehensive. For that you'll need to check the XWiki Reference API page.
Note that while most examples are written in Velocity you can use any other scripting language to access the same APIs.
Snippets
Make sure to check the Snippets wiki which contains plenty of small script examples that you can copy/paste and adjust for your needs.
Querying documents
See the Query Module for examples on how to perform queries on the wiki using a scripting language.
Create a new Document
For example in Velocity:
#set ($newDoc = $xwiki.getDocument('MySpace.MyPage'))
## Set its content (for example)
#set ($discard = $newDoc.setContent("new content"))
## The second parameter to save() indicates whether the save is a minor edit or not
#set ($discard = $newDoc.save("some comment explaining the save", true))
Accessing the request
You can access the HTTP Request by accessing the com.xpn.xwiki.web.XWikiServletRequest object through the request script variable.
For example in Velocity, to access an action HTTP parameter passed in the request you would write:
Note that this is a shortcut to:
Getting external content
You can use the following APIs to get content located at external URLs:
public String getURLContent(String surl) throws IOException
public String getURLContent(String surl, String username, String password, int timeout) throws IOException
public String getURLContent(String surl, int timeout) throws IOException
public byte[] getURLContentAsBytes(String surl, String username, String password)
public byte[] getURLContentAsBytes(String surl) throws IOException
For example in Velocity:
Add objects to a page
Here is a piece of Velocity script to show how it's possible to store a new object in one page:
#set($obj = $doc.newObject("XWiki.SomeClass"))
$obj.set("field1",$value1)
$obj.set("field2",$value2)
## Save the object in the page
$doc.save()
The "XWiki.SomeClass" class has to be created (through the class editor): field1 and field2 are property of the class. At the moment, this code works fine only if the user currently logged in has editing rights on the page, otherwise the Document.save() will not work.
Access objects in a page
Here is a piece of Velocity script to show how it is possible to access an object attached to the page, and read its fields :
#set($obj = $doc.getObject('SomeSpace.SomeClass'))
## Retrieve the raw value of the propertty "field1" for this object, provided
## a property called "field1" is actually defined in the class of this object
#set($rawValue = $obj.getProperty('field1').value)
SomeSpace.SomeClass[0] : field1 = "$rawValue"
## or value displayed (supports l10n or key-value properties)
#set($ValueDisplayed = $obj.field1)
#set($class = $obj.xWikiClass) ## access the class object representing SomeSpace.SomeClass
## return the property type: String, TextAreaDate, Boolean, ...
$class.get('field1').classType
You can also go through all the properties of an object, without knowing their respective names. That's how the default Class Sheet works, when you create a class using the Class Wizard.
#foreach($prop in $class.properties) ## go through all properties
<dt> *${prop.prettyName}* </dt>
<dd>$doc.display($prop.getName())</dd>
#end
Actually the line $doc.display(propertyName) can either display the property value, or generate an input field in the page, mapped to the property whose name is passed as argument (when you edit the page in inline mode). If you have a Velocity script that uses the display(propertyName) method to access properties of an object attached to the including page and you want to include it somewhere else you have to use the includeForm() Velocity macro in the including script:
See the includeForm() macro for more information.
Access objects from any page and loop over all objects of same Class
Here is a piece of Velocity script to show how it is possible to access an object attached to the page from another page, and read its fields:
(It is similar than previous code except you must "call" page before with $xwiki.getDocument.)
## Retrieve the first object (index [0]) among all objects attached to the page MySpace.MyDocWithMyClassObjects and of a certain class MySpace.MyClass
#set( $MyDoc = $xwiki.getDocument("MySpace.MyDocWithMyClassObjects"))
## get the document wich contains the class definition: this page has entries in the class editor
#set( $class = $xwiki.getClass("MySpace.MyClass"))
#foreach($prop in $class.properties) ## go through all properties
* ${prop.prettyName} : $MyDoc.display($prop.getName())
#end
If MySpace.MyDocWithMyClassObjects have many attached objects of MySpace.MyClass class (with different value)
#set($MyDoc = $xwiki.getDocument("MySpace.MyDocWithMyClassObjects"))
#set($class = $xwiki.getClass("MySpace.MyClass"))
## loop over all objects
#foreach($obj in $MyDoc.getObjects("MySpace.MyClass"))
* Object number $velocityCount
#set($discard = $MyDoc.use($obj))
#foreach($prop in $class.properties) ## go through all properties
** ${prop.prettyName} : $MyDoc.display($prop.getName())
#end
#end
Include a Velocity page into another Velocity page
See the Include In Velocity tutorial.
Redirecting to another page
It's possible to redirect the user to another page. This is useful for example when a page has been removed and you have given the URL to someone so you want the old page to redirect to the new page.
Example:
For more examples, see the Redirect Snippet.
Add an Attachment to a page
For example, in Velocity:
#set($content = "This is some small arbitrary content")
#set($discard = $doc.addAttachment("myfile.txt", $content.getBytes()))
#set($discard = $doc.save("some comment"))
{{/velocity}}
Add a new user to a List of Users xobject
Let's imagine that Space.Page contains an xobject having a users xproperty of type "List of Users" (and configured to be a multiselect).
The following code adds a new user reference to the list:
#set ($usersObject = $doc.getObject('Space.Page'))
#set ($referenceList = $usersObject.getValue('users'))
#set ($referenceList = "${referenceList},XWiki.NewUser")
#set ($discard = $usersObject.set('users', $referenceList))
#set ($discard = $doc.save('Added new user', true))
{{velocity}}
Create an XClass
The following example creates an XClass with a single mytextarea xproperty of type Text Area in the document Sandbox.TestClass.
#set ($mydoc = $xwiki.getDocument('Sandbox.TestClass'))
#set ($myinternaldoc = $mydoc.getDocument())
#set ($myclass = $myinternaldoc.getXClass())
#set ($discard = $myclass.addTextAreaField("mytextarea", "My Text Area", 100, 5))
#set ($discard = $mydoc.save('created doc + xclass'))
{{/velocity}}
Modify the last update date
#set ($mydoc = $xwiki.getDocument('Sandbox.WebHome'))
#set ($date = $datetool.toDate('yyyy-MM-dd', '2013-01-01'))
#set ($mydocinternal = $mydoc.getDocument())
#set ($discard = $mydocinternal.setDate($date))
#set ($discard = $mydocinternal.setMetaDataDirty(false))
#set ($discard = $mydocinternal.setContentDirty(false))
$xwiki.getXWiki().saveDocument($mydocinternal, "change update date", true, $xcontext.getContext())
{{/velocity}}
Find XDOM Blocks
You can access an AST (we all it the XDOM) of a document's content using the getXDOM() API (See Rendering Documentation for more). Then you can find all Blocks of a given type.
Example 1: Find all Headings in Sandbox.WebHome:
#set ($mydoc = $xwiki.getDocument('Sandbox.WebHome'))
#foreach ($block in $mydoc.getXDOM().getBlocks('class:HeaderBlock', 'DESCENDANT'))
* $block
#end
{{/velocity}}
Example 2: Display the "reference" parameter of all Include macros in Sandbox.WebHome:
#set ($mydoc = $xwiki.getDocument('Sandbox.WebHome'))
#foreach ($block in $mydoc.getXDOM().getBlocks('class:MacroBlock', 'DESCENDANT'))
#if ($block.id == 'include')
* Include macro reference parameter = $block.getParameter('reference')
#end
#end
{{/velocity}}
Mark a page as hidden
#set ($myDoc = $xwiki.getDocument('MySpace.MyPage'))
#set ($discard = $myDoc.setHidden(true))
## The second parameter to save() indicates whether the save is a minor edit or not
#set ($discard = $myDoc.save("some comment explaining the change", true))
{{/velocity}}
List all attachments of a page
#set ($myDoc = $xwiki.getDocument('Main.attachment.WebHome'))
#foreach ($attachment in $myDoc.getAttachmentList())
* $attachment.getFilename()
#end
{{/velocity}}