Creating an Extension
There are 2 types of Extensions:
- XAR Extensions: they are wiki pages packaged in a format that is called XAR (which stands for XWiki Archive). It's a ZIP file with a specific directory structure and an XML syntax to represent the wiki pages, along with a package metadata file.
- JAR Extensions: they are XWiki Components written in Java and packaged in a JAR.
Creating a XAR Extension
The simplest strategy is to create the wiki pages in a running XWiki instance and then to export them as a XAR.
Note that those wiki pages can contain a lot of things:
- pure content,
- scripts,
- applications (you can even use the Applications Within Minutes application to help create some simple application to match your needs),
- wiki macros,
- ... and a lot more
Building a XAR with Maven
If you wish to save your XAR sources under version control and be able to build it, we recommend using Maven. There's a plugin called the XAR Maven plugin to help with this.
Here's how you can save the XAR you got when exporting pages from the wiki into your source tree:
- create a [ROOT] directory to be the root of your Maven project
- add a pom.xml file (see below for more details)
- unzip the XAR into the [ROOT]/src/main/resources directory and remove the package.xml file (you don't need to save it since the Maven XAR plugin will regenerate it)
- run mvn xar:format to pretty format the wiki pages (XML files)
- run mvn install to automatically perform validation and generate the XAR
Authoring a Maven POM for a XAR
Here's an example of how your pom.xml could look like (adapt to your need).
Notice the usage of a Contrib Parent POM which automatically provides configuration for lots of things. To know more about how to use the Contrib Parent POM check the documentation for it on GitHub.
<!--
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.xwiki.contrib</groupId>
<artifactId>parent-platform</artifactId>
<version>8.4-11</version>
</parent>
<groupId>org.xwiki.contrib</groupId>
<artifactId>your-extension-id</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Your extension's name</name>
<packaging>xar</packaging>
<description>Your extension's description</description>
<scm>
<connection>scm:git:git://github.com/xwiki-contrib/(your extension id).git</connection>
<developerConnection>scm:git:[email protected]:xwiki-contrib/(your extension id).git</developerConnection>
<url>https://github.com/xwiki-contrib/(your extension id)</url>
</scm>
<developers>
<developer>
<id>scm id of developer 1</id>
<name>Full Name of developer 1 as registered on xwiki.org, e.g. Vincent Massol</name>
</developer>
...
<developer>
<id>scm id of developer N</id>
<name>Full Name of developer N as registered on xwiki.org, e.g. Vincent Massol</name>
</developer>
</developers>
<properties>
<!-- Don't check for API backward-compatibility here since there's no Java code. -->
If you're using a xwiki-commons parent POM that is >= 8.1M1 then you need to use:
<xwiki.revapi.skip>true</xwiki.revapi.skip>
Otherwise you should use:
<xwiki.clirr.skip>true</xwiki.clirr.skip>
<!-- The Extension name. If not defined, the <name> property is used -->
<xwiki.extension.name>Your extension's name</xwiki.extension.name>
<!-- The extension's category -->
<xwiki.extension.category>application</xwiki.extension.category>
<!-- Issue management -->
<xwiki.release.jira.skip>false</xwiki.release.jira.skip>
<xwiki.issueManagement.jira.id>(your jira project id)</xwiki.issueManagement.jira.id>
</properties>
</project>
See the section about Metadata below to understand what information you need to provide in your POM.
Creating a JAR Extension
XWiki has a notion of Components, and this is how it provides extensibility at the level of Java. XWiki itself is written as a set of Components. This allows extension writers to author Components that can replace (i.e. override) existing Components or add new Components to the system.
Here are some examples:
- Add a new Macro,
- Write a Listener,
- Implement a new wiki markup syntax,
- ... and a lot more
Follow the Creating an XWiki Component tutorial to learn how to both develop a Component and use Maven to build it.
Extension Metadata
It's important that you set the following information as they'll be used by XWiki's Extension Manager when the extension is installed in XWiki (see below):
- Extension id (<groupId> and <artifactId>), e.g. org.xwiki.contrib.blog and application-blog-ui.
- Name. This is the user-friendly name of your extension and it's displayed on http://extensions.xwiki.org. Specify it using the <xwiki.extension.name> maven property. E.g. Blog Application.
- Description. Keep it to one sentence. It's displayed on http://extensions.xwiki.org.
- Developers
- Category (using <xwiki.extension.category>). Valid values are listed here.
- SCM (Note: this is also required by the Maven Release plugin if you use it to release your extension)
- Issue Management (most of the time only the jira id as a Maven property like in the example)
- Exposed components that should be discoverable in the XWiki UI (e.g. Macros). This is done using an <xwiki.extension.components> entry. For example:<xwiki.extension.components>
org.xwiki.rendering.macro.Macro/figure
</xwiki.extension.components>
If you've modified the groupId or artifactId of the extension you need to tell it to the Extension Manager so that it can handle upgrades and understand it's the same extension being upgraded. For example if the extension previously had an extension id of tdelafosse:meeting-application and you're now using another id, you need to add the following property to your pom.xml:
...
<!-- Old names of this module used for retro compatibility when resolving dependencies of old extensions -->
<xwiki.extension.features>tdelafosse:meeting-application</xwiki.extension.features>
...
</properties>
Installing an Extension
There are 2 ways but the recommended one is to use the Extension Manager which you can find in the XWiki instance where you wish to install the extension in.
Using the Extension Manager
The advantage over the Manual way is that you don't need to regularly start/stop your XWiki instance and thus you don't occur the start wait times.
- Have a running XWiki instance configured with a local Extension Repository pointing to your Maven local Repository. Edit xwiki.properties and make sure you have the following set:extension.repositories=local:maven:file://${sys:user.home}/.m2/repository
extension.repositories=maven-xwiki:maven:http://nexus.xwiki.org/nexus/content/groups/public
extension.repositories=extensions.xwiki.org:xwiki:http://extensions.xwiki.org/xwiki/rest/ - Build your component and deploy it in your local Maven repository with mvn install
- Inside your running XWiki instance, go to the Extension Manager in the Admin UI (e.g. http://localhost:8080/xwiki/bin/admin/XWiki/XWikiPreferences?editor=globaladmin§ion=XWiki.AddExtensions) and click on Advanced Search and enter your extension's id and version and follow the instructions. (<groupId>:<artifactId> , e.g: org.xwiki.contrib:your-extension-id)
Note: If you are on Windows and the extension manager is not able to look up your extension, you might want to use an explicit path to your local maven repository. (for example, extension.repositories = maven-local:maven:file:C:/Users/jdoe/.m2/repository)
Manually
Don't use this method if your extension has non-core dependencies as otherwise it's more complex as you also need to copy all dependencies. In addition this won't test that your extension can be installed properly by users. This is listed for information purposes only but you should really use the Extension Manager instead.
For a XAR
- To build the component, issue mvn install. This generates a XAR in the target directory of your project.
- Inside your XWiki instance, go the Admin and Import the XAR.
For a JAR
- To build the component, issue mvn install. This generates a JAR in the target directory of your project.
- To install it into a XWiki instance, just copy that JAR file in XE_WAR_HOME/WEB-INF/lib where XE_WAR_HOME is where the XWiki WAR is deployed.
Deploying Extensions
If you wish to make your extension available to others to use, the best is to contribute it on extensions.xwiki.org. Go there and enter a name for your extension in the Contribute box and submit. Then document nicely your extension with instructions on how to use. The more screenshots the better! Here are some documentation guidelines.
Once your extensions is there, it means that any user of XWiki in the world will be able to find it and install it directly from his/her wiki!
You may also want to join a family and contribute your extension on XWiki Contrib so that it is developed and maintained collaboratively.