Web UI plugin modules allow you to insert links, tabs and sections of links into the Confluence web interface. They're not much use on their own, but when combined with XWork-WebWork Plugins they become a powerful way to add functionality to Confluence.
Sections and Items
Web UI plugins can consist of two kinds of plugin modules:
web-item
modules define links that are to be displayed in the UI at a particular location
web-section
modules define a collection of links to be displayed together
Web items or web sections (referred to collectively as 'web fragments') may be displayed in a number of different ways, depending on the location of the fragment and the theme under which it is being displayed.
Locations
In a number of places in the Confluence UI, there are lists of links representing operations relevant to the content being viewed. These are the locations that you can customise:
Location key |
Themeable? |
Sectioned? |
Description |
Availability |
system.admin |
|
|
The links in the left-hand menu on the global administrative console |
2.2 |
system.space |
|
|
The tabs in 'Browse Space' |
2.2 |
system.space.admin |
|
|
The links in the left-hand menu on the space administrative tab |
2.2 |
system.space.advanced |
|
|
The links in the left-hand menu on the space advanced tab |
2.2 |
system.space.pages |
|
|
The 'sub-tabs' in Browse Space → Pages |
2.2 |
system.space.labels |
|
|
The 'sub-tabs' in Browse Space → Labels |
2.2 |
system.space.actions |
|
|
The action icons in the top-right of most space-related views |
2.2 |
system.page |
|
|
The tabs for 'View Page' |
2.2 |
system.page.actions |
|
|
The action icons in the top right of the page view (eg. Watch this page) |
2.3 |
system.news |
|
|
The tabs for 'View News' |
2.2 |
system.labels |
|
|
The 'sub-tabs' in the global label view |
2.2 |
system.profile |
|
|
The tabs above the user profile |
2.2 |
- Those locations marked as being 'themeable' can be moved around, reformatted or omitted by Theme Plugins. The descriptions above refer to where they are located in the default theme.
- Locations marked as being 'sectioned' require that web items be grouped under web sections. In sectioned locations, web items that are not placed under a section will not be displayed.
- It is possible for themes to make any themeable locations sectioned, even when the default theme doesn't. We do not recommend this, as it would mean any plugin taking advantage of this would only be compatible with a particular theme.
Web Item Definition
Here's a sample atlassian-plugin.xml fragment for a web item:
<web-item key="spacelogo" name="Space Logo" section="system.space.admin/looknfeel" weight="40">
<label key="configure.space.logo" />
<link>/spaces/configurespacelogo.action?key=$helper.spaceKey</link>
<icon height="16" width="16">
<link>/images/icons/logo_add_16.gif</link>
</icon>
<condition class="com.atlassian.confluence.plugin.descriptor.web.conditions.NotPersonalSpaceCondition"/>
</web-item>
- The key is the required plugin module key, which must be unique within the plugin. It is also used in the UI for determining which module is currently being displayed.
- The name is a required displayable name for the module, only used in the plugin administrative UI
- The section is the required location into which this web item should be placed. For non-sectioned locations, this is just the location key. For sectioned locations it is the location key, followed by a slash ('/'), and the name of the web section in which it should appear
- The weight is required , and determines the order in which web items appear. Items are displayed top to bottom or left to right in order of ascending weight. (i.e. the 'lightest' weight is displayed first, the 'heaviest' weights sink to the bottom)
- The label element is required, and is the i18n key that will be used to look up the textual representation and mouse-over text of the link.
- The link element is required, and defines where the web item should link to. The contents of the link element will be rendered using Velocity, allowing you to put dynamic content in links. For more complex examples of links, see below.
- The icon element is optional, and defines an icon to display with or as the link. Note: In some cases the icon element seems to be required. Try adding it if your web section is not displaying properly.
- The condition element is optional, and defines a condition that must be satisfied for the web item to be displayed. If you want to 'invert' a condition, add an attribute 'invert="true"' to it. The web item will then be displayed if the condition returns false (not true).
Label elements
Label elements may contain optional parameters, as shown below:
<label key="navlink.attachments">
<param name="param0">$!helper.page.title</param>
<param name="param1">$!helper.numberOfAttachments</param>
</label>
- The parameters allow you to insert values into the label using Java's MessageFormat syntax.
- Parameter names must start with
param
and will be mapped in alphabetical order to the substitutions in the format string.
- Parameter values are rendered using Velocity, allowing you to include dynamic content
Link elements
Link elements may contain additional information:
<link linkId="editPageLink" accessKey="$helper.action.getTextStrict('navlink.edit.accesskey')">/pages/editpage.action?pageId=$helper.page.id</link>
- The linkId is optional, and provides an XML id for the link being generated.
- The accessKey is optional and provides an access key for the link being generated. The contents of this element will be rendered using Velocity, allowing you to generate an access key dynamically.
Condition elements
Condition elements must contain a class attribute with the fully-qualified name of a Java class. The referenced class:
- must implement
com.atlassian.confluence.plugin.descriptor.web.Condition
- must be able to be instantiated via a no-argument constructor
- will be auto-wired by Spring before any condition checks are performed
Condition elements can take optional parameters. These parameters will be passed in to the Condition's init()
method as a Map of String key/value pairs after autowiring, but before any condition checks are performed. For example:
<condition class="com.atlassian.confluence.plugin.descriptor.web.conditions.PagePermissionCondition">
<param name="permission">edit</param>
</condition>
Multiple condition elements can be included in a single web item. If a web item contains multiple conditions, all conditions must be satisfied for the web item to be displayed.
To invert a condition, add the attribute 'invert="true"' to the condition element. This is useful where you want to show the section if a certain condition is not satisfied.
Web Section Definition
Here's a sample atlassian-plugin.xml for a web section:
<web-section key="mail" name="Mail" location="system.space.admin" weight="300">
<label key="space-mail" />
<condition class="com.atlassian.confluence.plugin.descriptor.web.conditions.NotPersonalSpaceCondition"/>
</web-section>
- key, name, weight, label and condition are all the same as
web-item
- location is required, and serves the same purpose as section in
web-item
, except that a section can not be contained within another section.
- Web sections do not have links or icons.
Q and A
How do I make use of sections or web items in my own themes?
Take a look at how they are used in the default themes, you should be able to get a good idea of the necessary code. For example, here is some sample code from space.vmd
#foreach ($item in $action.webInterfaceManager.getDisplayableItems("system.space", $action.remoteUser, $helper))
<li><a href="$item.link.getDisplayableUrl($req, $helper)" #if ($context == $item.key) class="current" #end>
$item.label.getDisplayableLabel($req, $helper)
</a></li>
#end
Can I create new locations for web UI plugins in my own themes?
Yes. Just pick a new key for the location
or section
parameters of your plugin modules. By convention, you should probably use the standard 'inverted domain name' prefix so as not to clash with anyone else's plugins. We reserve all system.*
locations for Confluence's core use.
Once again, however, we don't recommend this as you end up with plugins that are only useful in your own themes. Try to at least provide an alternative set of UI modules for people who are using other themes and still want to access the same functionality. You could, for example, define alternative UI plugin modules that placed your functions in Confluence's standard locations, but have a <condition> that disabled them in favour of your custom locations if your theme was installed.
If I create a Web Item that links to my custom action, how do I make it appear in the same tabs/context as the other items in that location?
The best way is to look at the .vm file of one of the existing items in that location. You are most interested in the #applyDecorator
directive being called from that file. For example viewpage.vm
, which defines the "View" tab in the system.page
location has the following #applyDecorator
directive:
#applyDecorator("root")
#decoratorParam("helper" $action.helper)
#decoratorParam("mode" "view")
#decoratorParam("context" "page")
<!-- some stuff... -->
#end
If you were writing a plugin that was destined to be added as another item in the page tabs, your Velocity file for that action would also have to have a similar decorator directive around it:
#applyDecorator("root")
#decoratorParam("helper" $action.helper)
#decoratorParam("mode" "myPluginKey")
#decoratorParam("context" "page")
<!-- some stuff... -->
#end
Note that you should put you Web Item's plugin key as the "mode". This way, Confluence will make sure that the correct tab is highlighted as the active tab when people are viewing your action.