This page last changed on Jun 22, 2009 by rosie@atlassian.com.
In JIRA 4, portlets have been superceded by gadgets.
For details, please see Gadget Development.

Overview

A portlet displays summary information on project/issue data through the JIRA dashboard. This information can range from statistical data to quick links for commonly used filters.

With JIRA 3.0, the introduction of the plugin system aimed to provide a simple point of extensibility for custom features users may wish to add to JIRA. This tutorial will describe how to create a custom portlet within JIRA 3.0, using this plugin interface.

The following articles provide further detailed information on writing a JIRA 3 plugin:

A Portlet Plugin Module Primer

In order to make a custom portlet available within JIRA, it is necessary to create a portlet plugin module. As with all plugin modules, the portlet plugin will consist of the following components:

  • Java classes encapsulating portlet logic
  • Resource templates for display of the portlet
  • Plugin descriptor to enable the portlet module in JIRA

all contained within a single JAR file.

Portlet Logic

The Java classes include the necessary logic to retrieve the data used in configuring and displaying the portlet. The module class must implement com.atlassian.jira.portal.Portlet and will usually extend com.atlassian.jira.portal.PortletImpl. The PortletImpl interface provides methods to initialise the portlet through the parameters defined in the descriptor (name, key, thumbnail image, etc.) and retrieve the portlet template location. It is also possible to extend existing portlets to add further custom functionality.

Resource Templates

The second component consists of templates used to render the portlet - Velocity templates can be used here. The templates can include:

  • Dashboard view - the actual dashboard view

The plugin system parses the atlassian-plugin.xml file for any configuration properties associated with the portlet that are required in order to display the portlet. The plugin system constructs a suitable configuration screen requesting the user to specify values for these properties.

Other Resources

It is possible to include i18n property files also - so as to allow other users to easily translate the strings used in the portlet for different languages. The following portlet examples are fully internationalized and include default property files.

Portlets are added through the dashboard configuration screen. The portlet selection displays the title and description along with a thumbnail image which links to a full image preview of the actual portlet display. It is necessary to include these image files (both the thumbnail and full image) within the final plugin JAR. To make the process as simple as possible, the images must be manually extracted from the JAR and copied to the webapp/portlets/dashboard/thumbnails directory in order for JIRA to access them. The full image location is specified in the atlassian-plugin.xml file - JIRA will search for the 'thumbnail image' in the same location.

Plugin Descriptor

The portlet module descriptor is the only mandatory part of the plugin. It must be called atlassian-plugin.xml and be located in the root of the JAR file.

Here is a sample portlet module descriptor element:

<!--
    The module class must implement
        com.atlassian.jira.portal.Portlet
    and will usually extend:
        com.atlassian.jira.portal.PortletImpl
-->
<portlet key="assignedtome" name="Assigned Issues" class="com.atlassian.jira.portal.portlets.AssignedToMePortlet">
    <description key="portlet.assignedtome.description">i18n description</description>
    <!-- this template produces the eventual HTML of the portlet -->
    <resource type="velocity" name="view" location="templates/plugins/jira/portlets/assignedtome.vm" />
    <label key="portlet.assignedtome.name" />
    <!-- an optional thumbnail image used to preview the portlet for users -->
    <thumbnail>portlets/dashboard/thumbnails/assigned.gif</thumbnail>
    <!-- the permissions required to add this portlet (optional - not often required) -->
    <permission>assignable</permission>
    <objectdescriptor key="portlet.assignedtome.display.name" />
    <!-- the properties of this report which the user must select before running it -->
    <properties>
        <property>
            <key>numofentries</key>
            <name>portlet.assignedtome.field.numofentries.name</name>
            <description>portlet.assignedtome.field.numofentries.description</description>
            <type>long</type>
            <default>10</default>
        </property>
    </properties>
</portlet>

In this sample, the portlet logic is encapsulated in the AssignedToMePortlet Java class. The view template location is specified in the templates/plugins/jira/portlets directory. The preview image is located in the portlets/dashboard/thumbnails directory. The Assignable permission is required for users to add this portlet to their dashboards. Following that, the parameters required to configure the portlet are specified - in this case, a numeric field specifying the number of issues to display in the portlet. You can find the list of available permissions here

JIRA Development Kit

You can choose to develop your plugins however you wish. However, we recommend using Maven 1.0 and the JIRA Plugin Development Kit.

Maven is an ant-like build tool that downloads any specified project dependencies automatically (just one of the many features).

The JIRA Plugin Development Kit consists of a number of examples (including the ones discussed here) to help developers extend JIRA through the plugin interface as easily as possible.

Once the JIRA Plugin Development Kit has been setup, you need only run the command:

maven jar

to build the desired plugin. Using Maven is not a requirement - you can use ant or any other build tool, however, it will make your life a lot easier.

Examples

The following examples detail how to extend an existing system portlet and how to create custom portlets. Each example is included in the JIRA Plugin Development Kit. When compiled, the atlassian-jira-plugin-portlets-example-1.0.jar JAR includes each portlet and can be copied to the JIRA lib directory in order to make the portlets available within the system.

Example 1 - Extending an Existing System Portlet

In this example, an existing system portlet - 'Assigned To Me' - is extended to display the status of the issue. The original portlet displays a specified number of issues assigned to the current user, displaying the issue key, summary and priority.

This full source of this example is included in the development kit - the files of interest are:

  • src/etc/templates/historyportlet/assignedtomeextended.vm
  • src/etc/templates/historyportlet/issuesummaryextended.vm
  • src/etc/atlassian_plugins.xml
  • src/etc/com/atlassian/jira/plugin/portlet/example/assigned/assigned_portlet.properties
  • src/etc/portlets/dashboard/thumbnails/assignedextended.png
  • src/etc/portlets/dashboard/thumbnails/corner_assignedextended.png

In order to do this, it is only necessary to edit the view templates and i18n property files as all other aspects of the portlet can be reused. The information required to display the status is already passed to the template in the form of the issue itself - so the portlet logic does not need to be modified.

Firstly, the atlassian-plugin.xml file is created to include a new portlet module:

<atlassian-plugin key="com.atlassian.jira.plugin.portlet.example" name="JIRA Portlet Examples Plugin">
    <plugin-info>
        <description>Portlet Examples Plugin.</description>
        <version>1.0</version>
        <application-version min="3.0" max="3.0"/>
        <vendor name="Atlassian Software Systems Pty Ltd" url="http://www.atlassian.com"/>
    </plugin-info>

    <!-- An simple example of customising an existing portlet - adding the status of an issue to the template -->
    <portlet key="assignedtomeextended" name="Example: Assigned IssNues Extended"
        class="com.atlassian.jira.portal.portlets.AssignedToMePortlet">
        <description key="portlet.asssignedtome.extended.description">i18n description</description>
        <resource type="velocity" name="view" location="templates/assignedportlet/assignedtomeextended.vm" />
        <resource type="i18n" name="i18n" location="com.atlassian.jira.plugin.portlets.example.assigned.assigned_portlet" />
        <label key="portlet.assignedtome.extended.name" />
        <thumbnail>portlets/dashboard/thumbnails/assignedextended.png</thumbnail>
        <permission>assignable</permission>
        <objectdescriptor key="portlet.assignedtome.extended.display.name" />
        <properties>
            <property>
                <key>numofentries</key>
                <name>portlet.assignedtome.field.numofentries.name</name>
                <description>portlet.assignedtome.field.numofentries.description</description>
                <type>long</type>
                <default>10</default>
            </property>
        </properties>
    </portlet>

</atlassian-plugin>

As can be seen, the original AssignedToMePortlet Java class is reused - no code changes are necessary.

The remainder of the portlet definition specifies the following information:

  • the name and description properties
  • the location of the i18n files
  • the location of the thumbnail files
  • the parameters required to configure the portlet

The main change to note is the reference to a modified view template - one that displays the status. The modified view templates simply over-ride the templates used by the original 'Assigned to Me' portlet. The issuesummaryextended.vm includes the following section in order to display the issue status in the dashboard view:

<td nowrap width=1%>
    #displayConstantIcon($issue.getStatusObject())
</td>


The i18n property strings have also been modified (in order to change the portlet name and description). These i18n property strings are defined in files that are included in the final JAR.

Finally, the thumbnails displaying a preview of the portlet are included in the JAR also. However, the thumbnails need to be manually copied to the webapp/portlets/dashboard/thumbnails directory in order for JIRA to access them.

The portlet will appear on the dashboard once selected, displaying the status of each issue.

Example 2 - Recently Updated Issues

In this example, a custom portlet is coded to display the most recently updated issues within a specific project on the dashboard. The portlet can be configured to display a specified number of issues over a specified number of days in the past.

This full source of this example is included in the development kit - the files of interest are:

  • src/etc/templates/historyportlet/history.vm
  • src/etc/templates/historyportlet/issuesummaryhistory.vm
  • src/etc/atlassian_plugins.xml
  • src/etc/com/atlassian/jira/plugin/portlet/example/history/history_portlet.properties
  • src/etc/portlets/dashboard/thumbnails/history.png
  • src/etc/portlets/dashboard/thumbnails/corner_history.png
  • src/java/com/atlassian/jira/plugin/portlet/example/history/HistoryPortlet.java

Firstly, the atlassian-plugin.xml file is created/modified to include the new portlet:

    <!-- A simple example portlet - displays recently issues updated for a specific user -->
    <portlet key="history" name="Example: Recently Updated Issues"
        class="com.atlassian.jira.plugin.portlet.example.history.HistoryPortlet">
        <description key="portlet.history.description">i18n description</description>
        <resource type="velocity" name="view" location="templates/historyportlet/history.vm" />
        <resource type="i18n" name="i18n" location="com.atlassian.jira.plugin.portlets.example.history.history_portlet" />
        <label key="portlet.history.name" />
        <thumbnail>portlets/dashboard/thumbnails/assignedextended.png</thumbnail>
        <objectdescriptor key="portlet.history.display.name" />
        <properties>
            <property>
                <key>projectid</key>
                <name>portlet.history.field.project.name</name>
                <description>portlet.history.field.project.description</description>
                <type>select</type>
                <values class="com.atlassian.jira.portal.ProjectValuesGenerator"/>
            </property>
            <property>
                <key>dayshistory</key>
                <name>portlet.history.field.dayshistory.name</name>
                <description>portlet.history.field.dayshistory.description</description>
                <type>long</type>
                <default>3</default>
            </property>
            <property>
                <key>numofentries</key>
                <name>portlet.history.field.numofentries.name</name>
                <description>portlet.history.field.numofentries.description</description>
                <type>long</type>
                <default>10</default>
            </property>
        </properties>
    </portlet>

As can be seen, a custom Java class - HistoryPortlet - encapsulates the logic required for configuring and displaying this portlet.

The remainder of the portlet definition in atlassian-plugin.xml specifies the following information:

  • the name and description properties
  • the location of the i18n files
  • the location of the thumbnail files
  • the parameters required to configure the portlet

In this case, the portlet requires three parameters to correctly display the data:

  • projectid - a select field specifying the project on which the portlet will focus. The possible project options available are retrieved through another JIRA class - com.atlassian.jira.portal.ProjectValuesGenerator.
  • dayshistory - a numeric field specifying the number of days to look back over.
  • numofentries - a numeric field specifying the number of issues to display.

The class HistoryPortlet encapsulates the logic necessary to retrieve the issues most recently updated within the specified project over the specified number of days.

The view templates are very similar to the ones used in the 'Assigned To Me Extended' example discussed above - the main changes taking place with the name and description properties.

Again, as with the previous example, the i18n property files and image previews are also included. The thumbnails need to be manually copied to the webapp/portlets/dashboard/thumbnails directory in order for JIRA to access them.

The portlet will appear on the dashboard once selected, displaying the specified number of recently updated issues within the specified project.

Document generated by Confluence on Oct 06, 2009 00:31