Web UI Plugin Module

JIRA Documentation

Index

Web UI Plugin module

Web UI plugin modules are available in Jira 3.7 and later.
Web UI plugin modules allow you to insert links, tabs and sections of links into the Jira web interface

Sections and Items

Web UI plugins can consist of two kinds of plugin modules:

  • web-item modules define links that will be displayed in the UI at a particular location
  • web-section modules define a collection of links that will 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.

Locations

In a number of places in the Jira UI, there are lists of links representing operations relevant to the content being viewed. These are the locations and sections that you can customise:

Location key Sections Dynamic Sections? Description
system.admin project
usersgroups
globalsettings
schemes
issuefields
issuesettings
exportimport
options
system
The administrative menu links on the left-hand side of the Administration page
system.preset.filters   The filter links on the right hand side of Browse Project page and on the project portlets of the dashboard. Note that the filter links are defined only once and is reused in both places.
Links are displayed in two columns where the right column contains the every second link, and the rest in the left column
system.top.navigation.bar   System links on the top navigation bar
The web-item can optionally specify up to 2 URL prefix that will be used to determine whether the link is selected or not. This is done by adding a param element with names: selected and selected2
system.user.navigation.bar links
views
Links on the top-right user navigation bar.
web-item's must be added to either the links or views section.
  • links section allows its links to be plain or popup links. To make a link to be a popup link, set a param element with name isPopupLink as true. Additional parameters can be set to dynamically set the height (windowHeight), width (windowWidth) and whether to have scrollbars (scrollbars) for the popup
  • views section displays all its links as icons and require the icon element
system.browse.project.operations
Project operation links on the 'Browse Project' Page
system.view.project.operations
Project operation links on the 'View Project' Page
  • Locations marked as being 'Dynamic Sections' allows new sections to be added. Whereas unmarked locations will not display new sections added to that location and require the items to be added to the existing sections. If there are no sections, the items should be added to the location key itself.

Web Item Definition

Here's a sample atlassian-plugin.xml fragment for a web item:

<web-item key="popup_recent_history" name="Recent History Popup Link" section="system.user.navigation.bar/popups" weight="10">
    <label key="bodytop.history" />
    <tooltip key="tooltip.history" />
    <link linkId="user_history">/secure/popups/recenthistory.jsp</link>
    <param name="windowHeight">$historyWindowHeight</param>
    <context-provider class="com.atlassian.jira.plugin.web.contextproviders.HeightContextProvider" />
    <condition class="com.atlassian.jira.plugin.web.conditions.UserHasIssueHistoryCondition" />
</web-item>

The web-item has the following attributes:

Attribute Description Required?
key 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.
name Displayable name for the module, only used in the plugin administrative UI
section 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
weight 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). Jira's system sections and links weight start from 100 and 10 respectively. The weight is incremented by 10 for each in sequence so that there is ample space to insert your own sections and links

The web-item has the following elements

Element Description Required?
label Is the i18n key that will be used to look up the textual representation of the link.
tooltip Is the i18n key that will be used to look up the textual mouse-over text of the link.
link 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.
icon Defines an icon to display with or as the link.
param Defines a key/value pair available from the web-item. This is handy if you want to use additional custom values from the UI.
context-provider Allows dynamic addition to the velocity context available for various web-item elements (in XML descriptors only). Currently only one context-provider can be specified per web item and section.
condition 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).
conditions Defines the logical operator type to evaluate its condition elements. By default 'AND' will be used.

Label elements

Label elements may contain optional parameters, as shown below:

<label key="common.concepts.create.new.issue">
    <param name="param0">$helper.project.name</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. ie. param0 is {0}, param1 is {1}, param2 is {2} etc
  • Parameter values are rendered using Velocity, allowing you to include dynamic content

Tooltip elements

Tooltip elements have the same attributes and parameters as the label elements.

Link elements

Link elements may contain additional information:

<link linkId="create_link" accessKey="$authcontext.i18nBean.getText('alt.text.createnewissue.accessKey')">/secure/CreateIssue!default.jspa</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.

Icon elements

Icon elements have a height and width attribute. The location of the icon is specified within a link element:

<icon height="16" width="16">
    <link>/images/icons/print.gif</link>
</icon>

Param elements

Param elements represent a Map of key/value pairs, where each entry corresponds to the param elements attribute: name and value respectively.

<param name="key" value="value" />

its value can be retrieved from within the velocity view by (where $item is an WebItemModuleDescriptor):

$item.webParams.get("key") <!-- retrieve the value -->
$item.webParams.getRenderedParam("key", $user, $helper) <!-- retrieve the velocity rendered value -->

If the value attribute is not specified the value will be set to the body of the element. ie. the following two param elements are equivalent

<param name="isPopupLink" value="true" />
<param name="isPopupLink">true</param>

Context-provider element

Adds to the velocity context available to the web-section and web-item modules. This means you can add what you need to the context to build more flexible section and item elements. Currently only one context-provider can be specified per module, additional context-providers are ignored.

context-provider element must contain a class attribute with the fully-qualified name of a Java class. The referenced class:

  • must implement com.atlassian.plugin.web.ContextProvider
  • will be auto-wired by Pico before any additions to the velocity context

For example, the following context-provider will add historyWindowHeight and filtersWindowHeight to the context.

The following example: HeightContextProvider extends AbstractJiraContextProvider, which implements ContextProvider. The AbstractJiraContextProvider conveniently extracts the User and JiraHelper from the context map you would otherwise have to do manually.

public class HeightContextProvider extends AbstractJiraContextProvider
{
    private final ApplicationProperties applicationProperties;

    public HeightContextProvider(ApplicationProperties applicationProperties)
    {
        this.applicationProperties = applicationProperties;
    }

    public Map getContextMap(User user, JiraHelper jiraHelper)
    {
        int historyIssues = 0;
        if (jiraHelper != null && jiraHelper.getRequest() != null)
        {
            UserHistory history = (UserHistory) jiraHelper.getRequest().getSession().getAttribute(SessionKeys.USER_ISSUE_HISTORY);
            if (history != null)
            {
                historyIssues = history.getIssues().size();
            }
        }
        int logoHeight = TextUtils.parseInt(applicationProperties.getDefaultBackedString(APKeys.JIRA_LF_LOGO_HEIGHT));
        String historyHeight = String.valueOf(80 + logoHeight + (25 * historyIssues));
        String filterHeight = String.valueOf(205 + logoHeight);
        return EasyMap.build("historyWindowHeight", historyHeight,
                             "filtersWindowHeight", filterHeight);
    }
}

The above HeightContextProvider can be used by nesting the following element in a web-item module.

<context-provider class="com.atlassian.jira.plugin.web.contextproviders.HeightContextProvider" />

The newly added context entries historyWindowHeight and filtersWindowHeight can be used in the XML module descriptors just like normal velocity context variables by prefixing it with the dollar symbol ($)

<!-- pass the value of historyWindowHeight as a parameter called windowHeight (see param element above for its usage) -->
<param name="windowHeight">$historyWindowHeight</param>

<!-- set the link's label to print the value of filtersWindowHeight -->
<label>filter window height is: $filtersWindowHeight</label>

Condition and Conditions elements

Conditions can be added to the web-section and web-item modules to display them only when all its conditions are true.

Condition elements must contain a class attribute with the fully-qualified name of a Java class. The referenced class:

  • must implement com.atlassian.plugin.web.Condition
  • will be auto-wired by Pico 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.jira.plugin.web.conditions.JiraGlobalPermissionCondition">
    <param name="permission">admin</param>
</condition>

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.
Conditions elements are composed of a collection of condition/conditions elements and a type attribute. The type attribute defines what logical operator is used to evaluate its collection of condition elements. The type can be one of AND or OR.
For example: The following conditions is true if the current user is a system admin OR a project admin

<conditions type="OR">
    <condition class="com.atlassian.jira.plugin.web.conditions.JiraGlobalPermissionCondition">
        <param name="permission">admin</param>
    </condition>
    <condition class="com.atlassian.jira.plugin.web.conditions.UserHasProjectsCondition">
        <param name="permission">project</param>
    </condition>
</conditions>

Web Section Definition

Here's a sample atlassian-plugin.xml for a web section:

<web-section key="usersgroups" name="Users and Groups Section" location="system.admin" weight="110">
    <label key="admin.menu.usersandgroups.users.and.groups" />
    <condition class="com.atlassian.jira.plugin.web.conditions.UserIsAdminCondition" />
</web-section>
  • key, name, weight, label, tooltip, condition and conditions 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.

Velocity Context

The following table lists out the velocity context available for use in the XML descriptor and velocity views.

Name Type Description
user User Currently logged in user
helper JiraHelper Convenient class which holds information such as the current request and selected project
xmlutils XMLUtils Utilities for basic XML reading
textutils TextUtils Utilities for common String manipulations
urlcodec JiraUrlCodec Utility for encoding a string
outlookdate OutlookDate Class to give a nice String representation of a date
authcontext JiraAuthenticationContext User locale dependant utility class. Can get the current user, locale, I18nBean (for internationalisation) and OutlookDate
dateutils DateUtils Utilities for displaying date/time
externalLinkUtil ExternalLinkUtil A simple utility class that lets you resolve external links that may need to change, because of partner sites and such
requestContext VelocityRequestContext A context that allows for different implementations depending on whether it is running in the scope of a web request, or via email.
req HttpServletRequest current request
baseurl String The base URL for this instance (velocityRequestContext.getBaseUrl())

Examples

Heres a simple example that uses both the web UI module and the webwork plugin module.
A webwork plugin module defines a URL-addressable 'action', allowing JIRA's user-visible functionality to be extended or partially overridden. In this example, the action simply prints "Hello World" or greets a given name. However the action can only be executed by entering a specific URL that is not linked from Jira. This is where the web UI plugin comes in play, by adding the specific URL as a link from the Jira web interface.

The following plugin modules will:

  • Register a new webwork action that prints "Hello World" or Hello to a specific name
  • Adds a new section to the administration menu called Example 1 Section
  • Adds 3 links under the new section:
<webwork1 key="HelloWorld" name="Hello World Example Action">
    <description key="action.hello.world.desc">Webwork plugin example that prints hello world. Can also specify a name to say hello to.</description>
    <actions>
        <action name="HelloWorldAction" alias="Hello">
            <view name="success">/templates/example/helloworld.vm</view>
        </action>
    </actions>
</webwork1>

<web-section key="example1" name="Example 1 Section" location="system.admin" weight="105">
    <label key="section.example.one.label" />
</web-section>

    <web-item key="google_home" name="Google Home" section="system.admin/example1" weight="10">
        <description key="item.google.home.desc">Simple link to google.com.</description>
        <label key="item.google.home.label" />
        <link linkId="google_home">http://google.com</link>
    </web-item>

    <web-item key="hello_world" name="Webwork Hello World Example" section="system.admin/example1" weight="20">
        <description key="item.hello.world.desc">Link to the Hello World action. No name parameter specified.</description>
        <label key="item.hello.world.label" />
        <link linkId="hello_world">/secure/Hello.jspa</link>
    </web-item>

    <web-item key="hello_user" name="Webwork Hello User Example" section="system.admin/example1" weight="30">
        <description key="item.hello.user.desc">Link to the Hello World action with name set to the current user's full name.</description>
        <label key="item.hello.user.label" />
        <link linkId="hello_user">/secure/Hello.jspa?name=${user.fullName}</link>
        <condition class="com.atlassian.jira.plugin.web.conditions.UserLoggedInCondition" />
    </web-item>

Here is the screenshot of the new administration menu:

The new section "Example 1 Section" appears in between the "Project" and "Users, Groups & Roles" as its weight is in between the two.

Get the full sample plugin from the Jira Plugin Development Kit. The sample shows how to combine a simple webwork module with a web UI module to provide you with an interface to your plugin from Jira. You can find a real life application of this in the JIRA Subversion plugin (for Jira 3.7 compatible versions only).

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.
  1. Apr 19, 2007

    Ferenc Kiss says:

    Guys, I think that the XML snippets are wrong: the condition classes are located...

    Guys, I think that the XML snippets are wrong: the condition classes are located in the com.atlassian.jira.plugin.webfragment.conditions.JiraGlobalPermissionCondition package, not in com.atlassian.jira.plugin.web.conditions.JiraGlobalPermissionCondition!(At least in 3.8 I got ClassNotFoundException.)

  2. May 17, 2007

    Keertikar Pandey says:

    Can someone provide codesnippet for creating WEBITEM plugins.

    Can someone provide code-snippet for creating WEB-ITEM plugins.