1. Gadget Developer Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1 Gadget Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Getting Started with Gadget Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2 Writing an Atlassian Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.1 Creating your Gadget XML Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.1.1 Example of Gadget XML Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.2 Using Substitution Variables and Directives in your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.3 Allowing Configuration Options in your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.4 Including Features into your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.5 Packaging your Gadget as an Atlassian Plugin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.6 Internationalising your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.7 Using Web Resources in your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.8 Using Atlassian REST APIs in your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.9 Providing User Authentication for Gadgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.10 Using the Atlassian Gadgets JavaScript Framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.10.1 Gadget Object API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.10.2 Creating a Gadget JavaScript Object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.10.3 Gadget Developers' JavaScript Cookbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2.11 Managing Caching for your Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.3 Gadget Containers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.4 Examples of Gadgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5 Tutorials on Writing a Gadget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5.1 Tutorial Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5.1.1 Template for Plugin Gadget Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5.1.2 Template for Standalone Gadget Tutorial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.6 Gadgets and JIRA Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.7 Gadgets and Dashboards Version Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 Development Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.1 Reference Documents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.2 Development FAQ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.2.1 Finding Known Issues and Workarounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.2.2 Developing Standalone or Plugin Gadgets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2.2.3 Hints for Developing in iGoogle Sandbox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Gadgets and Dashboards Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Application Programming Interface or API (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.2 Atlassian Gadgets (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.3 Atlassian Gadgets Support Level or AGSL (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.4 Container (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.5 Dashboard (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.6 Directive (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.7 Directory (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.8 Gadget (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.9 Gadget Publisher Plugin (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.10 Gadget Renderer Plugin (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.11 Host Application (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.12 OAuth (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.13 OpenSocial (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.14 OpenSocial Plugin (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.15 Plugin Exchange Manager (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.16 Plugin Framework 2 (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.17 Reference Implementation (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.18 REST Plugin Manager (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.19 Service Provider Interface or SPI (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.20 Shared Access Layer or SAL (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.21 Shindig (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.22 Trusted Application Authentication (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3.23 Universal Plugin Manager (Glossary Entry) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
3
4
5
5
10
12
13
14
19
21
22
24
24
24
26
30
42
50
50
51
51
51
51
56
58
59
60
60
61
61
62
63
63
65
65
65
65
65
65
65
65
65
66
66
66
66
66
66
66
66
66
67
67
67
67
67
Gadget Developer Documentation
Getting Started
At heart, Atlassian gadgets are Google gadgets. Atlassian gadgets use the new Google gadgets.* API defined by the OpenSocial
specification. In addition, you will probably want to use some of the Atlassian extensions to the gadget specification. You will also want to
package your gadget as an Atlassian plugin, along with plugin modules that allow your gadget to interact with the Atlassian applications such
as JIRA and Confluence.
Read our introduction to gadget development. Then follow a tutorial or jump right into writing a gadget.
Main Topics
Gadget XML Specification
See how to define your gadget via an XML file.
Atlassian Gadgets JavaScript Framework
Use our JavaScript libraries to create your gadget, extract data from an Atlassian application and display it in the gadget UI.
Atlassian Plugin SDK
Many gadgets go hand-in-hand with Atlassian plugins. Get started with developing an Atlassian plugin.
Atlassian Development Hubs
Developer Network
Plugin Framework
Gadgets
REST APIs
Confluence
JIRA
GreenHopper
Bamboo
Crowd
FishEye/Crucible
JIRA Mobile Connect
Resources
The big list of Atlassian gadgets
Version matrix of gadgets and applications
Javadoc
Plugin Exchange
Gadget user's and administrator's guide
Help
Gadget development FAQ
Answers from the community
Mailing lists at my.atlassian.com
Atlassian Partners
Feature requests and bug reports
Atlassian developer blog
Atlassian Developer Blog
The road to HAMS 3.0 - Transaction boundaries
Make your plugin sizzle with new Plugin Exchange enhancements
Testing's In Session
AtlasCamp 2011
Let the Developer Party Begin: AtlasCamp 2011 Save the Date
JavaScript Cookbook
Adding a Chart to the Issue Navigator
Adding a Reload Option to your Gadget
Adding Something to your Gadget Footer
Adjusting the Gadget Height when the Window is Resized
Making Ajax Calls
Making your Gadget Reload when Resized
Restricting Edit Permissions on your Gadget Preferences
Showing the Config Screen on Initial Load Only
Specifying Required Features for the Framework
Specifying Required Resources for the Framework
Theming your Gadget Dynamically
Using Authentication in your Gadget
Using Cookies in your Gadget
Using Special UserPrefs for the Framework
Gadget Development
At heart, Atlassian gadgets are Google gadgets. Atlassian gadgets use the new Google gadgets.* API defined by the OpenSocial
specification. In addition, you will probably want to use some of the Atlassian extensions to the gadget specification. You will also want to
package your gadget as an Atlassian plugin, along with plugin modules that allow your gadget to interact with the Atlassian applications such
as JIRA and Confluence.
Gadget Development Table of Contents
Getting Started with Gadget Development
Writing an Atlassian Gadget
Creating your Gadget XML Specification
Example of Gadget XML Specification
Using Substitution Variables and Directives in your Gadget
Allowing Configuration Options in your Gadget
Including Features into your Gadget
Packaging your Gadget as an Atlassian Plugin
Internationalising your Gadget
Using Web Resources in your Gadget
Using Atlassian REST APIs in your Gadget
Providing User Authentication for Gadgets
Using the Atlassian Gadgets JavaScript Framework
Gadget Object API
Creating a Gadget JavaScript Object
Field Definitions
REST Resource for Validating Gadget Configuration
Gadget Developers' JavaScript Cookbook
Adding a Chart to the Issue Navigator
Adding a Reload Option to your Gadget
Adding Something to your Gadget Footer
Adjusting the Gadget Height when the Window is Resized
Making Ajax Calls
Making your Gadget Reload when Resized
Restricting Edit Permissions on your Gadget Preferences
Showing the Config Screen on Initial Load Only
Specifying Required Features for the Framework
Specifying Required Resources for the Framework
Theming your Gadget Dynamically
Using Authentication in your Gadget
Copy of Using Authentication in your Gadget
Using Cookies in your Gadget
Using Special UserPrefs for the Framework
Managing Caching for your Gadget
Gadget Containers
Examples of Gadgets
Tutorials on Writing a Gadget
Tutorial Templates
Template for Plugin Gadget Tutorial
Template for Standalone Gadget Tutorial
Gadgets and JIRA Portlets
Gadgets and Dashboards Version Matrix
RELATED TOPICS
Reference Documents
Gadgets and Dashboards Documentation
Getting Started with Gadget Development
At heart, Atlassian gadgets are Google gadgets. Atlassian gadgets use the new Google gadgets.* API defined by the OpenSocial
specification. In addition, you will probably want to use some of the Atlassian extensions to the gadget specification. You will also want to
package your gadget as an Atlassian plugin, along with plugin modules that allow your gadget to interact with the Atlassian applications such
as JIRA and Confluence.
Introducing Gadgets, Containers, Plugins and Applications
A gadget is essentially an XML file containing the gadget specification. You will use recognised XML elements to define the following:
1.
2.
3.
4.
5.
Gadget characteristics, such as the author's name (your name), the gadget title and description, preferred sizing, etc.
A screenshot and/or thumbnail image that containers can display to show users what your gadget looks like.
Required features that containers must provide for your gadget.
User preferences, where your gadget can allow its users to customise certain aspects of the gadget display.
The content section, where you use define the content that your gadget will display. This is where you add the HTML and JavaScript
functions that produce your gadget's output.
As the gadget developer, you create the static XML file and make it available on a server. The dashboard or other container will pull the XML
file from the server or plugin where it resides, and render it. The container may, for example, display the gadget inside an iframe on a
dashboard. Or the container may display the gadget on a web page via a wiki macro.
Here is an overview of how gadgets, containers, plugins and applications interact with each other:
Google gadgets that support the OpenSocial specification will run on OpenSocial containers.
A simple Google gadget will run on an Atlassian container, including the dashboard of any Atlassian application that supports
gadgets.
In principle, an Atlassian gadget will run on an OpenSocial container.
You can customise your Atlassian gadget to interface in funky ways with your Atlassian applications, via the Atlassian Plugin
Framework. See Packaging your Gadget as an Atlassian Plugin.
Writing a Simple Gadget
If you have never written a gadget before, you can start by writing a simple Google gadget:
1. Become familiar with Google gadgets. There are two Google gadget developer guides, one for the earlier 'legacy' version of the
Google gadget API and one for the new version which supports OpenSocial. Make sure you use the new guide.
2. Take a look at our hints for developing in iGoogle sandbox, compiled from our own experiences with Google gadgets.
3. Read the guide to getting started with OpenSocial.
Writing an Atlassian Gadget
Now move on to write an Atlassian Gadget.
RELATED TOPICS
Gadget Developer Documentation
Writing an Atlassian Gadget
To write an Atlassian gadget, you can use the Atlassian extensions to the gadget specification:
1.
2.
3.
4.
Take a look at our example gadgets.
See the Atlassian gadget XML specification
Write your gadget, referring to the advanced topics below.
Deploy your gadget on a container.
More Advanced Topics
Creating your Gadget XML Specification
Using Substitution Variables and Directives in your Gadget
Allowing Configuration Options in your Gadget
Including Features into your Gadget
Packaging your Gadget as an Atlassian Plugin
Internationalising your Gadget
Using Web Resources in your Gadget
Using Atlassian REST APIs in your Gadget
Providing User Authentication for Gadgets
Using the Atlassian Gadgets JavaScript Framework
Managing Caching for your Gadget
RELATED TOPICS
Gadget Developer Documentation
Creating your Gadget XML Specification
This is the reference guide for the XML file you will write to define your Atlassian gadget.
On this page:
Overview
Atlassian Gadgets and Google Gadgets
Example of an Atlassian Gadget XML Specification
Module Element
ModulePrefs Element
Require Element
Optional Element
Param Element
Preload Element
Icon Element
Locale Element
Link Element
OAuth Element and its Children
UserPref Element
Enum Element
Content Element
Overview
A gadget is essentially an XML file containing the gadget specification. You will use recognised XML elements to define the following:
1.
2.
3.
4.
5.
Gadget characteristics, such as the author's name (your name), the gadget title and description, preferred sizing, etc.
A screenshot and/or thumbnail image that containers can display to show users what your gadget looks like.
Required features that containers must provide for your gadget.
User preferences, where your gadget can allow its users to customise certain aspects of the gadget display.
The content section, where you use define the content that your gadget will display. This is where you add the HTML and JavaScript
functions that produce your gadget's output.
Atlassian Gadgets and Google Gadgets
When writing an Atlassian gadget you may use additional XML elements, attributes and features that extend the Google gadgets XML
specification.
On the page below, we give an overview of elements in the standard Google gadget specification that are supported by Atlassian gadgets. In
cases where the Atlassian gadget specification differs from Google, we have added a comment like this:
(Comment about the difference in Atlassian gadgets.)
Example of an Atlassian Gadget XML Specification
Below is a truncated example of a gadget specification. You can also take a look at a longer example of a real gadget.
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="JIRA Issues" author_email="adent@example.com" directory_title="JIRA Issues"
screenshot="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues-screenshot.png"
thumbnail="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues-thumbnail.png">
<Require feature="minimessage" />
<Optional feature="dynamic-height" />
</ModulePrefs>
<UserPref name="show_date" display_name="Show Dates?" datatype="bool" default_value="true"/>
<UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="true"/>
<UserPref name="num_entries" display_name="Number of Entries:" default_value="5"/>
<Content type="html">
<![CDATA[
Hello, world!
]]>
</Content>
</Module>
Module Element
This element indicates that the XML file contains a gadget. The element contains the entire gadget definition.
ModulePrefs Element
The <ModulePrefs> section specifies the gadget's characteristics, such as title, author, preferred sizing, and so on. Users who are viewing
the gadget cannot change the values in this section.
You can use substitution variables, like __UP_myuserpref__, in the attributes in the <ModulePrefs> and <UserPref> sections, where
myuserpref matches the name attribute of a user preference. See the Google documentation on user preference substitution variables.
Parent Element: GADGETS:Module
Example:
<ModulePrefs title="JIRA Issues" author_email="adent@example.com" directory_title="JIRA Issues"
screenshot="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues-screenshot.png"
thumbnail="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues-thumbnail.png">
<Require feature="minimessage" />
<Optional feature="dynamic-height" />
</ModulePrefs>
Attributes:
Attribute
Name
Required
/Optional
Description
title
Optional
The title of the gadget. This is a standard Google gadget attribute. See the Google Gadgets XML Reference.
Refer also to the directory_title attribute below.
title_url
Optional
If you specify this value, the gadget title will link to this URL. This is a standard Google gadget attribute. See
the Google Gadgets XML Reference.
description
Optional
A description of the gadget. This is a standard Google gadget attribute. See the Google Gadgets XML
Reference.
author
Optional
Your name, as creator of the gadget. This is a standard Google gadget attribute. See the Google Gadgets
XML Reference.
author_email
Optional
Your email address, as creator of the gadget. This is a standard Google gadget attribute. See the Google
Gadgets XML Reference.
screenshot
Optional
The address of an image that a container or directory can use to illustrate the gadget. This is a standard
Google gadget attribute. See the Google Gadgets XML Reference.
This attribute is not referenced by Atlassian Gadgets. Atlassian Gadgets does not
make use of this feature, so it will have no effect on an Atlassian container. You may
include the feature in your gadget if you want it to be used in other containers.
thumbnail
Optional
The address of a thumbmail image (120x60 pixels) that a container or directory can use to illustrate the gadget.
This is a standard Google gadget attribute. See the Google Gadgets XML Reference.
directory_title
Optional
The name of the gadget as it should appear in the gadget directory. If the value of your title attribute
contains user preference substitution variables (like __UP_userpref__), then you will supply a plain text
value in the directory_title attribute. See the Google documentation on user preference substitution
variables.
Require Element
The <Require> element instructs the container that the gadget needs a specific feature to be provided by the container.
Parent Element: Module/GADGETS:ModulePrefs
Example:
<Require feature="minimessage" />
<Require feature="dynamic-height" />
Attributes:
Attribute Name
Required
/Optional
Description
feature
Required
The name of the feature that the gadget requires. See our guide to including features into your gadget.
Optional Element
The <Optional> element instructs the container that the gadget can make use of a specific feature, if the container is able to provide it.
Parent Element: Module/GADGETS:ModulePrefs
Example:
<Optional feature="dynamic-height" />
Attributes:
Attribute
Name
Required
/Optional
Description
feature
Required
The name of the feature that the gadget will use if provided by the container. See our guide to including
features into your gadget.
Param Element
The <Param> element allows you to supply parameters for features requested via the <Require> or <Optional> elements.
Parent Element: Module/ModulePrefs/GADGETS:Optional and Module/ModulePrefs/GADGETS:Require
Example:
<Optional feature="gadget-directory">
<Param name="categories">
JIRA
Charts
</Param>
</Optional>
Attributes:
Attribute
Name
Required
/Optional
Description
name
Required
A name-value pair giving the parameter and its value. You can read more about the <Param> element in the
Google Gadgets XML Reference.
Preload Element
The <Preload> element instructs the container to fetch data from a remote source during the gadget rendering process.
Parent Element: Module/GADGETS:ModulePrefs
The Atlassian usage of this element is identical to the usage described in the Google Gadgets XML Reference.
Icon Element
This attribute is not referenced by Atlassian Gadgets. Atlassian Gadgets does not make use of this feature, so it will
have no effect on an Atlassian container. You may include the feature in your gadget if you want it to be used in other
containers.
The <Icon> element specifies a 16x16 pixel image that containers can associate with a particular gadget.
Parent Element: Module/GADGETS:ModulePrefs
Locale Element
The <Locale> element specifies the locales supported by your gadget. For more information, please refer to the page on internationalising
your gadget.
Parent Element: Module/GADGETS:ModulePrefs
Link Element
This attribute is not referenced by Atlassian Gadgets. Atlassian Gadgets does not make use of this feature, so it will
have no effect on an Atlassian container. You may include the feature in your gadget if you want it to be used in other
containers.
The <Link> element specifies a container-specific link. For example, a container may link to your gadget to provide online help.
Parent Element: Module/GADGETS:ModulePrefs
OAuth Element and its Children
The <OAuth> element specifies your gadget's use of the OAuth protocol for authentication. For more information on this element and its
child elements, please refer to the page on user authentication for gadgets.
Parent Element: Module/GADGETS:ModulePrefs
Child Elements: Service, Request, Access and Authorization — Please refer to the page on user authentication for gadgets.
UserPref Element
The <UserPref> section allows your gadget to give users a way of supplying their preferences and other user-specific information, called
'user preferences'. These user input fields are turned into user interface controls when the gadget runs. When the gadget is displayed on
iGoogle, the user preferences are accessible from the 'Edit settings' dropdown menu. In Atlassian gadgets, the menu option is 'Edit'.
As a gadget developer, you are entirely free to choose the user preference name.
The container handles generation of the configuration UI, saves the settings and provides an API to access the settings in JavaScript.
For example, a gadget that displays a list of JIRA issues may allow the user to choose whether to display the issue summaries and to specify
how many issues should be displayed.
You can use substitution variables, like __UP_myuserpref__, in the attributes in the <ModulePrefs> and <UserPref> sections, where
myuserpref matches the name attribute of a user preference. See the Google documentation on user preference substitution variables.
See the discussion of gadget configuration options.
Parent Element: GADGETS:Module
Example:
<UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="true"/>
<UserPref name="num_entries" display_name="Number of Entries:" default_value="5"/>
Attributes:
Attribute
Name
Required
/Optional
Description
name
Required
The name of the user preference. This is a standard Google gadget attribute. See the Google Gadgets XML
Reference.
display_name
Optional
The text displayed next to the preference input field. This is a standard Google gadget attribute. See the
Google Gadgets XML Reference.
urlparam
Optional
The string to pass as the parameter name for content type="url". This is a standard Google gadget attribute.
See the Google Gadgets XML Reference.
datatype
Optional
The data type of this attribute. This is a standard Google gadget attribute. See the Google Gadgets XML
Reference.
required
Optional
Boolean argument (true or false) indicating whether this user preference is required. The default is false. This
is a standard Google gadget attribute. See the Google Gadgets XML Reference.
default_value
Optional
A default value for the user preference. This is a standard Google gadget attribute. See the Google Gadgets
XML Reference.
Enum Element
The <Enum> element allows you to specify enumerated values for your GADGETS:user preference, when you have given a datatype of
enum.
Parent Element: Module/GADGETS:UserPref
The Atlassian usage of this element is identical to the usage described in the Google Gadgets XML Reference.
Content Element
The <Content> section is where it all happens!
In this section, you will define the type of content, and either include the content itself or provide a URL to pull in the content from an external
source. You will combine the attributes and user preferences with programming logic and formatting information to make the gadget do what
you want it to do.
There are two main types of gadget content, distinguished by the type attribute of the <Content> element.
Type url gadgets include content from a remote site, but do not have full access to features of the container. This type of gadget is
supported for compatibility with existing legacy iGoogle gadgets, but is considered deprecated and should generally be avoided when
creating new gadgets.
Type html gadgets include the content directly inside the <Content> element. This includes all of the HTML, CSS, and JavaScript code
that the container will render in the gadget's iframe. This content must be enclosed in a CDATA section to avoid having the gadget
specification parser interpret the embedded HTML markup as XML. For a guide to the JavaScript functionality available, please refer to our
JavaScript API reference guide and the Gadgets API Reference.
Parent Element: GADGETS:Module
Example:
<Content type="html">
<![CDATA[
<strong>Hello, world!</strong>
]]>
</Content>
Attributes:
Attribute
Name
Required
/Optional
Description
type
Optional
The type of content. The possible values are html and url. The default is html.
href
Required for
type="url"
, and not
allowed for
other content
types.
String that provides a destination URL.
view
Optional
The container view in which this content should be displayed. Gadgets can define multiple content sections,
each with a different view. The views supported by Atlassian containers are default for the standard view of
a gadget on a page alongside other gadgets and content, and canvas for the maximised view of a single
gadget on a page by itself. Other containers may support additional view types. If the same content section
should be displayed in more than one view, you can specify multiple views, separated by commas.
RELATED TOPICS
Writing an Atlassian Gadget
Gadget Developer Documentation
Example of Gadget XML Specification
Below is the code from the JIRA Introduction gadget.
Note about Path to Resource
Note that the resource com.atlassian.jira.gadgets:common is specific to JIRA.
The path to the Atlassian Gadgets JavaScript Framework is as follows:
In Atlassian Gadgets 1.0.x, the JavaScript framework is available in JIRA only and is not part of the Atlassian Gadgets framework.
The path in JIRA 4.0.x is:
#requireResource("com.atlassian.jira.gadgets:common").
In Atlassian Gadgets 2.0 and later, the JavaScript framework has been extracted from JIRA and made part of the Gadgets
framework. The path is:
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
The JIRA Introduction Gadget
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs
title="__MSG_gadget.introduction.title__"
directory_title="__MSG_gadget.introduction.title__"
description="__MSG_gadget.introduction.description__"
author="Atlassian"
author_affiliation="Atlassian" author_location="Sydney, Australia"
title_url="http://www.atlassian.com/"
screenshot="#staticResourceUrl("com.atlassian.jira.gadgets:average-age-chart-gadget",
"intro-screenshot.png")"
thumbnail="#staticResourceUrl("com.atlassian.jira.gadgets:average-age-chart-gadget",
"intro-thumb.png")">
<Optional feature="gadget-directory">
<Param name="categories">JIRA</Param>
</Optional>
<Require feature="dynamic-height" />
<Require feature="settitle" />
#supportedLocales("gadget.common,gadget.introduction")
</ModulePrefs>
<Content type="html">
<![CDATA[
#requireResource("com.atlassian.jira.gadgets:common")
#includeResources()
<div id="intro-content"><div class="fullyCentered loading"></div></div>
<script type="text/javascript">
jQuery.namespace("jira.app.intro");
jira.app.intro = function(){
var response = function(){
var resize = function(){gadgets.window.adjustHeight();};
return function(response){
if (response.rc != 200){
AJS.log("Error on server call
'__ATLASSIAN_BASE_URL__/rest/gadget/1.0/intro'. Return code: " + response.rc);
var fragment =
response.text.match(/<body[^>]*>([\S\s]*)<\/body[^>]*>/);
if (fragment && fragment.length > 0) {
jQuery("body").html("<div style=\"padding:0 20px\">" + fragment[1]
+ "</div>");
resize();
}
return;
}
if (response.data && response.data.html){
jQuery("#intro-content").removeClass("loading").html(response.data.html);
}
else {
jQuery("#intro-content").removeClass("loading").html("__MSG_gadget.introduction.welcome__");
}
resize();
};
}();
var setTitle = function(){
var isLocal = function(){return
window.location.href.indexOf("__ATLASSIAN_BASE_URL__/plugins/servlet/gadgets/ifr") == 0;};
var instanceNameResponse = function(response){
if (response.data && response.data.instanceName){
gadgets.window.setTitle(response.data.instanceName + ":
__MSG_gadget.introduction.title__");
}
};
return function(){
if (!isLocal()){
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] =
gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.METHOD] =
gadgets.io.MethodType.GET;
gadgets.io.makeRequest("__ATLASSIAN_BASE_URL__/rest/gadget/1.0/instanceName",
instanceNameResponse, params);
}
};
}();
return function(){
setTitle();
var params = {};
params[gadgets.io.RequestParameters.CONTENT_TYPE] =
gadgets.io.ContentType.JSON;
params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.GET;
gadgets.io.makeRequest("__ATLASSIAN_BASE_URL__/rest/gadget/1.0/intro",
response, params);
};
}();
gadgets.util.registerOnLoadHandler(jira.app.intro);
</script>
]]>
</Content>
</Module>
RELATED TOPICS
Creating your Gadget XML Specification
Using Substitution Variables and Directives in your Gadget
The Atlassian Gadgets framework allows you to specify substitution variables and #-directives in your gadget specification XML file that will
be replaced by generated content at run time.
On this page:
Substitution Variables
Atlassian Base URL Variable
Directives
Substitution Variables
The Atlassian Gadgets framework supports the standard substitution variables as defined in the Google documentation on user preference
substitution variables. These are variables like __UP_myuserpref__, in the attributes in the <ModulePrefs> and <UserPref> sections,
where myuserpref matches the name attribute of a user preference.
In addition, the following Atlassian-specific substitution variables are available.
Atlassian Base URL Variable
At run time, this variable will be replaced with the base URL of the host application (e.g. JIRA) that is serving the URL.
Note that this only works with plugin gadgets, since the translation is done by the gadget publisher, not the renderer. (The renderer does
the standard user pref and msg substitutions.)
Format:
__ATLASSIAN_BASE_URL__
Note: There is a double underscore at the beginning and at the end of the variable.
Example 1:
Here is an HTML snippet from the <Content> section of your gadget XML specification using the __ATLASSIAN_BASE_URL__ variable:
<img src="__ATLASSIAN_BASE_URL__/download/resources/com.atlassian.jira.gadgets/loading.gif"
height="35" width="35"/>
At run time, the above section of the gadget XML will be replaced with the following:
<img src="http://myhost.com:port/myapp/download/resources/com.atlassian.jira.gadgets/loading.gif"
height="35" width="35"/>
Example 2:
Here is a script snippet from the <Content> section of your gadget XML specification:
gadgets.io.makeRequest("__ATLASSIAN_BASE_URL__/rest/gadget/1.0/intro", response, params);
At run time, the above section of the gadget XML will be replaced with the following:
gadgets.io.makeRequest("http://myhost.com:port/myapp/rest/gadget/1.0/intro", response, params);
Directives
Our software (JIRA, FishEye etc) is packaged software that can be installed on customers' servers. We want our gadget developers to be
able to write gadgets that can retrieve information from any server, rather than from a specific web service or URL. So we have developed a
templating layer that sits on top of the gadget specification.
The Atlassian Gadgets framework allows you to specify #-directives in your gadget specification XML file that will be replaced by generated
content at run time. These #-directives are provided by the Atlassian Gadget Publisher plugin. They work for any gadget that is provided as a
plugin in an Atlassian application. The #-directives do not work for gadgets that are served from an external web server.
#-directives are sometimes also called 'macros' or 'pseudo-macros'.
Specific uses of #-directives:
Internationalising your Gadget – #supportedLocales
Using Web Resources in your Gadget – #requireResource, #includeResources
Using the Atlassian Gadgets JavaScript Framework – #oauth, #supportedLocales, #requireResource,
#includeResources
RELATED TOPICS
Creating your Gadget XML Specification
Writing an Atlassian Gadget
Gadget Developer Documentation
Allowing Configuration Options in your Gadget
This page gives an overview of the options available for allowing users to configure their instance of your gadget.
Security Note
Keep in mind that user preferences are stored in the container server, and are passed as URL parameters to the gadget
rendering server. You may want to be careful about what you put in there. In particular, a shipping gadget would never
want to store a username and password in user preferences, because then anyone with read access to a shared
dashboard with that gadget would be able to get the owner's login information. See user authentication guidelines.
On this page:
Setting User Preferences via the UserPref Element in the Gadget XML
Handling Configuration Inside your Gadget
Setting User Preferences via the UserPref Element in the Gadget XML
You can make use of the user preferences section of your gadget XML specification, where you can declaratively specify a set of
configurable options. See our guide to the gadget XML specification.
Each user preference has a name, a display name, a data type and a default value. You can also flag a user preference as required or
optional.
To access the user preferences from your gadget, you can use one or more of the following:
The user preferences JavaScript API, as described in the OpenSocial JavaScript API.
Specially-formatted tokens in the gadget XML file that are automatically substituted by the gadget renderer. These tokens look like
this: __UP_pref_name__.
JavaScript that sets the user preferences via the setprefs feature. See our guide to including features into your gadget.
Advantages of this Configuration Method
Development is easy. Just declare what you want in your gadget XML specification.
The container handles generation of the configuration UI, saves the settings and provides an API to access the settings in
JavaScript.
You can make use of automatic substitution in the gadget specification content, including substitution in the gadget title and other
metadata as well as the body content.
It is easy for users to figure out how to change the settings, because the container handles the configuration consistently for all
gadgets.
Disadvantages of this Configuration Method
It is inflexible. You are limited to a small number of data types, have no control over the UI, and the only validation you can do is to
set fields as required or optional.
The user preferences are static. There is no way to change the number or type of configuration settings programatically. Enum type
preferencess (rendered as a radio button or select list) can only have values that are hardcoded in the specification file. This means
that they are not useful for something like choosing a project from JIRA.
Both iGoogle and Atlassian Gadgets currently refresh the whole page when you save a user preference form.
Both iGoogle and Atlassian Gadgets (via Shindig) automatically HTML-escape values returned from prefs.getString(). (See
SHINDIG-89.) This means:
If you're using the value as literal HTML, you must not double-escape it.
If you're using the value in some other way (in a URL for example) then you must unescape it.
Handling Configuration Inside your Gadget
The other option is to handle configuration yourself, inside the gadget. This is the approach used by the Remember the Milk gadget, for
example. In this case, you can store the settings in a user preference of type hidden, using the setprefs API as described in the Google
developer guide, or you can come up with some other way to store the settings. You might be interested in looking at the json API for
serialising data.
Advantages of this Configuration Method
You can do whatever you want in your configuration UI: Load dynamic data, provide fancy UI controls, use Flash or Java, hide and
show sections depending on what users enter. And so on.
You can store the data however you want: Post it back to the application server, keep it in a cookie, use a Google Gears database.
If you want to, you can still use user preferences to store the values and save yourself the effort of figuring out where to put the data.
Because everything happens inside the gadget, you can avoid reloads and dynamically refresh the parts of your gadget that are
affected when configuration settings change.
Disadvantages of this Configuration Method
This method demands a lot more work. You have to write a lot of code to do things that the container handles automatically for
UserPref. For example, if you want your gadget's title to be based on a user preference, you will have to use the settitle feature to
do that yourself.
There are no established conventions or guidelines for this yet.
You will need to provide your own UI for entering the configuration mode, since the edit command provided by the container only
works for UserPref.
RELATED TOPICS
Creating your Gadget XML Specification
Writing an Atlassian Gadget
Gadget Developer Documentation
Including Features into your Gadget
Changed:
The auth-refresh feature is available in Atlassian Gadgets 1.1.3.
Changed:
The auth-refresh feature is automatically included in every gadget in Atlassian Gadgets 1.1.4 and 2.0.4.
A 'feature' is a JavaScript library that provides specific functionality for inclusion into your gadget. This page gives an overview of how you
can use a feature in your gadget and a list of available features.
Using a Feature in your Gadget
To create a gadget that uses a particular feature, such as dynamic height adjustment, you will do the following:
1. Include the feature library via a <Require> element or an <Optional> element in your gadget XML specification. The format is:
<ModulePrefs
title="My Gadget">
<Require feature="my-feature-name"/>
</ModulePrefs>
Here is a simple example:
<ModulePrefs
title="My Height-Adjusting Gadget">
<Require feature="dynamic-height"/>
</ModulePrefs>
2. Write some JavaScript code to use the feature. The JavaScript code goes in the <Content> element of your gadget XML
specification. The JavaScript APIs are described in the OpenSocial JavaScript API and in our JavaScript API reference guide.
List of Features
An unadorned list of features is available from our code repository. Below we provide more detail about the features.
Supported
in
Atlassian
Gadgets?
Feature
Name
Description
Specified
by
Fully
supported
auth-refresh
This 'authentication refresh' feature is available in Atlassian Gadgets 1.1.3 and later versions of
1.1.x, and in 2.0.4 and all later versions.
Shindig
This feature is automatically included in every gadget
In Atlassian Gadgets 1.1.4 and later versions of 1.1.x, and in 2.0.4 and later,
this feature is automatically included in every gadget that is hosted in an
Atlassian Gadgets container. You do not need to add the auth-refresh
feature yourself. There is also no way to exclude the feature from your gadget.
It is inserted into every gadget by the Atlassian OpenSocial Plugin.
The authentication refresh feature causes the dashboard to verify and refresh the authentication
of every gadget on a regular basis. Every twelve minutes the dashboard will request a new
security token for each gadget on the dashboard. It will then make an RPC call to each gadget
so that gadgets.io.makeRequest will use the new token when making requests. The
auth-refresh feature also sets up an RPC handler to receive the new security token. This feature
fixes AG-661 for any gadgets that are displayed on a dashboard. The fix does not apply to
standalone gadgets.
Fully
supported
atlassian.util
Allows a gadget to retrieve the base URL for the renderer server. Example:
Atlassian
Gadgets
<Module>
<ModulePrefs title="My Gadget">
<Optional feature="atlassian.util"/>
</ModulePrefs>
<Content type="html">
<![CDATA[
<div id="main">
<script language="javascript">
function showRendererBaseUrl() {
document.getElementById("main").innerHTML =
atlassian.util.getRendererBaseUrl();
};
gadgets.util.registerOnLoadHandler(showRendererBaseUrl);
</script>
</div>
]]>
</Content>
</Module>
Because this feature is specific to Atlassian Gadgets, we recommend that you
use <Optional> rather than <Required> when specifying this feature in
your gadget. Otherwise the gadget will not work in other containers.
Not
supported
Not
supported
analytics
Google Analytics
OpenSocial
caja
Support for Caja, a Google project aiming to allow web applications to provide active content
safely, simply, and flexibly. The basis of the project is that a subset of Javascript provides an
object-capability language.
OpenSocial
Not
referenced
content-rewrite
The content-rewrite feature defines a set of rewriting operations that a container can perform on
rendered and proxied content. It also defines rules to allow developers to control which content
the rewriter can operate on.
Tip: During development, you may find this feature useful to disable the automatic caching
provided by Shindig, so that your gadget resources will be re-loaded when you re-load the page.
Otherwise you will have to restart the container in order to see the updated values in your
gadget. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Optional feature="content-rewrite">
<Param name="expires">86400</Param>
<Param name="include-url"></Param>
<Param name="exclude-url">excluded</Param>
<Param name="exclude-url">moreexcluded</Param>
<Param name="minify-css">true</Param>
<Param name="minify-js">true</Param>
<Param name="minify-html">true</Param>
</Optional>
</ModulePrefs>
See the OpenSocial Gadgets API Specification.
Fully
supported
core.io
Provides remote content retrieval functions. See the OpenSocial gadgets.io API reference.
OpenSocial
Note that you do not need to explicitly request this feature with a <Required>
or <Optional> element. This feature is provided automatically to all gadgets.
Fully
supported
core
Provides core gadget support, including JavaScript APIs for manipulating JSON data, escaping
and unescaping strings, and accessing user preferences. See the OpenSocial gadgets.json
API reference, the OpenSocial gadgets.Prefs API reference, and the OpenSocial
gadgets.util API reference.
OpenSocial
Note that you do not need to explicitly request this feature with a <Required>
or <Optional> element. This feature is provided automatically to all gadgets.
Fully
supported
dynamic-height
Gives a gadget the ability to resize itself. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="dynamic-height"/>
</ModulePrefs>
You will call the JavaScript function gadgets.window.adjustHeight() whenever there is a
change in content, or another event occurs that requires the gadget to resize itself. See the
OpenSocial gadgets.window API reference. You may also find useful information in the
Google documentation on creating a user interface.
Fully
supported
flash
Allows you to embed a Flash movie into your gadget. Format:
<ModulePrefs
title="My Gadget">
<Require feature="flash"/>
</ModulePrefs>
You will call the JavaScript function gadgets.flash.embedFlash() to embed a .swf file in
your gadget and display it in a designated location. Note that to use this feature, all resources
must be bundled in a .swf file. See the OpenSocial gadgets.flash API reference. You may
also find useful information in the Google documentation on creating a user interface.
OpenSocial
Fully
supported
gadget-directory
Allows a gadget to specify details for its directory listing, such as the category in which the
gadget should be listed. Format:
Atlassian
Gadgets
<ModulePrefs
title="My Gadget">
<Optional feature="gadget-directory">
<Param name="categories">
JIRA
Charts
</Param>
</Optional>
</ModulePrefs>
The only recognized parameter is categories — the list of directory categories that this
gadget should appear in, one per line. Valid values are "JIRA", "Confluence", "FishEye",
"Crucible", "Crowd", "Clover", "Bamboo", "Admin", "Charts", "External Content", and "Other".
Gadgets that don't specify a directory category, or that specify only invalid categories, will be
listed in "Other".
Because this feature is specific to Atlassian Gadgets, we recommend that you
use <Optional> rather than <Required> when specifying this feature in
your gadget. Otherwise the gadget will not work in other containers.
Not
supported
Fully
supported
locked-domain
minimessage
OpenSocial
A MiniMessage is a temporary message displayed to users from within a gadget. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="minimessage"/>
</ModulePrefs>
See the OpenSocial gadgets.MiniMessage API reference. You may also find useful
information in the Google documentation on creating a user interface.
Fully
supported
Not
supported
Not
supported
Not
supported
Not
supported
Not
supported
Not
supported
oauthpopup
Manages popup windows for OAuth. See our detailed instructions on OAuth and the OpenSocial
gadgets.oauth.Popup API reference.
OpenSocial
opensocial-0.6
OpenSocial
opensocial-0.7
OpenSocial
opensocial-current
OpenSocial
opensocial-reference
OpenSocial
opensocial-templates
OpenSocial
pubsub
Allows your gadget to publish and subscribe to message channels. See the OpenSocial
gadgets.pubsub API reference.
This feature is not related to the Atlassian directory publish and subscribe
feature (see Atlassian Gadgets 2.0 Release Notes), despite the similar name.
The OpenSocial pubsub feature is meant to allow gadgets on a page to
communicate with each other. It is not actually specified by OpenSocial
currently, but planned to be standardised in a future version of the
specification.
OpenSocial
Fully
supported
rpc
Provides operations for making remote procedure calls for gadget-to-container,
container-to-gadget, and gadget-to-gadget communication. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="rpc"/>
</ModulePrefs>
You need to specify "rpc" as a required feature if you are using the gadgets.rpc JavaScript
API directly. If you are using only features that happen to rely upon gadgets.rpc, such as
settitle, dynamic-height, then the rpc feature will be implicitly included and you do not
need to include it explicitly. But you should not rely on this auto-inclusion if you are using the
API directly, as this behaviour may differ in other containers. See the OpenSocial
gadgets.rpc API reference.
Fully
supported
setprefs
Allows you to set the values for user preferences programmatically, without the user's direct
participation. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="setprefs"/>
</ModulePrefs>
See the OpenSocial gadgets.Prefs API reference. You may also find useful information in
the Google documentation on saving state.
Fully
supported
settitle
Allows you to set your gadget's title programmatically. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="settitle"/>
</ModulePrefs>
See the OpenSocial gadgets.window API reference. You may also find useful information in
the Google documentation on creating a user interface.
Not
referenced
skins
Allows you to manage the skin of your gadget programmatically. Format:
OpenSocial
<ModulePrefs
title="My Gadget">
<Require feature="skins"/>
</ModulePrefs>
See the OpenSocial gadgets.skins API reference.
Fully
supported
tabs
Allows you to add a tabbed user interface to your gadget. Format:
<ModulePrefs
title="My Gadget">
<Require feature="tabs"/>
</ModulePrefs>
See the OpenSocial gadgets.TabSet API reference. You may also find useful information in
the Google documentation on creating a user interface.
OpenSocial
views
Partially
supported
A view is a location in a container where a gadget is displayed. Different views have different
characteristics. For example, a container might have a view that shows gadgets in a small
format, and a view that shows gadgets in full page format. Atlassian Gadgets supports the
following views:
default — The standard view of a gadget, displayed in a small box on the page, possibly with
other gadgets. You can also use the aliases 'DEFAULT', 'DASHBOARD', 'profile', or 'home'.
canvas — The maximised view of a gadget when displayed by itself on the page.
OpenSocial
You need to specify "views" as a required feature if you are using the gadgets.views
JavaScript API directly. If you just need to use the canvas view, it is enough to include a content
section with view="canvas" and you do not need to specify the feature. Format:
<ModulePrefs
title="My Gadget">
<Require feature="views"/>
</ModulePrefs>
See the OpenSocial gadgets.views API reference. You may also find useful information in
the Google documentation on creating a user interface.
Partial support
Atlassian Gadgets provides only partial support of the "views" feature. Only
the getSupportedViews function is known to work. The
requestNavigateTo function is known not to work. The other functions
have not yet been tested, so may or may not work.
Restricting edit permissions on your gadget preferences
There is an Atlassian-specific extension to the views feature that allows you
to restrict who can edit your gadget preferences. See Restricting Edit
Permissions on your Gadget Preferences.
In the above table we show the level of support provided in Atlassian Gadgets for each feature:
Fully supported — Atlassian Gadgets provides full support for this feature. It will work on an Atlassian container.
Partially supported — Atlassian Gadgets supports some of the functionality provided by this feature. The table above tells you
which aspects are supported.
Not referenced — Atlassian Gadgets does not make use of this feature, so it will have no effect on an Atlassian container. You may
include the feature in your gadget if you want it to be used in other containers.
Not supported — Atlassian Gadgets does not support this feature and your gadget will not work on an Atlassian container if you
<Require> the feature. To use the feature in containers where it is available while still remaining compatible with Atlassian
Gadgets, you must use the <Optional> element to specify the feature, then test for the presence of the feature using the
gadgets.util.hasFeature function.
In the above table we have also categorised the features as follows:
Specified by OpenSocial — Most features are described in the OpenSocial JavaScript API.
Specified by Atlassian Gadgets — Additional features are provided specifically by the Atlassian Gadgets framework. These
features will work on an Atlassian Gadgets container but probably not on another OpenSocial container.
RELATED TOPICS
Creating your Gadget XML Specification
Using the Atlassian Gadgets JavaScript Framework
Writing an Atlassian Gadget
Gadget Developer Documentation
Packaging your Gadget as an Atlassian Plugin
This page tells you how to add your gadget to an Atlassian application (JIRA, Confluence, etc) as a plugin.
In short: Add a <gadget> module type to your atlassian-plugin.xml file.
On this page:
Standalone Gadget or Plugin?
Embedding your Gadget into a Plugin
Prerequisites
Purpose of the Gadget Module Type
Configuration
Example
URL for Published Gadgets
Standalone Gadget or Plugin?
How feasible is it to create an Atlassian gadget that consists purely of HTML, CSS and Javascript? Assuming that the Confluence or JIRA (or
whatever) REST API could do everything that the gadget needs, can you bypass the plugin side of things altogether?
You can choose to write a standalone gadget or a gadget embedded in a plugin.
A standalone gadget consists entirely of HTML, CSS and Javascript, all contained within the gadget XML file. To retrieve data from
an application, you can use a REST API, for example.
Alternatively you can write a gadget and a plugin, and embed the gadget into the plugin XML using the gadget plugin module. The
plugin needs to be installed into the Atlassian application, such as JIRA or Confluence.
Limitations if you do not embed your gadget in a plugin:
You will not be able to use #-directives. This means that, if your gadget is requesting data from an Atlassian application, the gadget
can only access a single, specific instance of that application because you will need to hard-code the base URL.
It is significantly more difficult to use the Atlassian Gadget JavaScript Framework, because you will need to code everything that is
normally automatically generated by the #supportedLocales and #includeResources directives.
That said, there are two main reasons why you may be interested in writing standalone gadgets:
It is a much simpler way to write very basic gadgets. This provides an easier way to learn how to write gadgets.
A non-plugin gadget may be sufficient if your gadget is for your own company's internal use with a single Atlassian application/site.
You may want to write gadgets that request data from some non-Atlassian system or web service, in order to integrate that data into
an Atlassian application such as JIRA or Confluence.
Embedding your Gadget into a Plugin
The rest of this page describes the gadget module type that you will use to embed your gadget within an Atlassian plugin.
Prerequisites
Your version of the Atlassian application must support gadgets. See the gadget version compatibility matrix.
Your version of the Atlassian application must support the Atlassian Plugin Framework version 2.2 or later. See the plugin framework
version compatibility matrix.
Your plugin must be an OSGi-based plugin, as supported by the Atlassian Plugin Framework.
You will need to install the REST plugin module type, if not already bundled with the application.
Purpose of the Gadget Module Type
Gadget plugin modules enable you to add your gadget to an Atlassian application (JIRA, Confluence, etc) as a plugin. Your gadget can then
make use of the application's remote API to fetch data and interact with the application.
Configuration
The element for the Gadget plugin module is gadget. It allows the following attributes for configuration:
Attributes
Name
Required
Description
key
The key attribute is a standard module key, so it is required and must be unique within the plugin across
all module types. Atlassian Gadgets does not use this key for anything special, so you can choose any
key you like.
location
The location attribute can be either the relative path to a resource within the plugin, or the absolute URL
of an externally-hosted gadget.
Example
The syntax of the module type is:
<atlassian-plugin name="Hello World" key="example.plugin.helloworld" plugins-version="2">
<plugin-info>
<description>A basic gadget module</description>
<vendor name="Atlassian Software Systems" url="http://www.atlassian.com"/>
<version>1.0</version>
</plugin-info>
<gadget key="unique-gadget-key" location="path/to/gadget.xml"/>
</atlassian-plugin>
Default
URL for Published Gadgets
Gadgets published by an Atlassian container (such as JIRA or Confluence) are provided by the REST plugin module built into the Atlassian
Gadgets framework. The URL of published gadgets has the following format — with context:
Or without context:
Example:
RELATED TOPICS
Creating your Gadget XML Specification
Writing an Atlassian Gadget
Overview of REST Implementation using the REST Plugin Module
REST Plugin Module
Internationalising your Gadget
This page gives an overview of the standard gadget API for internationalisation, and details of the features provided specifically by the
Atlassian Gadgets framework.
On this page:
Overview of the Google Gadgets API for Internationalisation and Localisation
Additional Features Provided by Atlassian Gadgets
#supportedLocales Directive
Overview of the Google Gadgets API for Internationalisation and Localisation
Atlassian gadgets support internationalisation and localisation as defined in the Google gadgets API.
Message Bundles
Any text that is visible to users, and therefore needs translating, will live in external XML files called message bundles. You will have one
message bundle for the original language, plus a number of additional message bundles for the other supported languages.
Message bundles are XML files with a top element of <messagebundle>. Each message bundle contains the translated strings for a given
locale. Each string is identified by a unique name that is the same across all your message bundles.
Message bundles can be hosted at any URL and can be shared between applications.
Using the Message Bundles in your Gadget
In your gadget XML specification you will have a list of <Locale> elements that specify the message bundles used by your gadget. The
<Locale> tag lives in the <ModulePrefs> section of the gadget XML specification and links the language to the relevant message bundle.
Please refer to the Google documentation for more details.
Additional Features Provided by Atlassian Gadgets
The Atlassian Gadgets framework allows you to specify #-directives in your gadget specification XML file that will be replaced by generated
content at run time. These #-directives are provided by the Atlassian Gadget Publisher plugin. They work for any gadget that is provided as a
plugin in an Atlassian application. The #-directives do not work for gadgets that are served from an external web server.
#-directives are sometimes also called 'macros' or 'pseudo-macros'.
You can use the #-directive described below with any Atlassian application that supports language packs
Alternatively, you can choose to create your own message bundles and code your own <Locale> elements instead of using the #-directive
described below.
#supportedLocales Directive
The Atlassian Gadgets framework scans your gadget specification XML file. If it encounters a #supportedLocales directive, it will:
Retrieve the language and country information for all of the installed language packs.
Replace the #supportedLocales directive with a <Locale> element for each combination of language and country, as required
in the gadget XML specification.
The messages attribute of each <Locale> element will point to a location in the application that publishes the gadget. This location provides
a dynamically-generated message bundle created by finding all of the internationalisation property keys that begin with one of the prefixes
specified in the #supportedLocales directive.
Parent Element: <ModulePrefs>
Format:
#supportedLocales("mygadget.prefix")
where mygadget.prefix is a prefix common to the message keys defined in your plugin's internationalisation file. It is possible to specify
multiple prefixes by separating them with commas, for example #supportedLocales("gadget.common,gadget.introduction").
Example:
Here is a snippet of the gadget XML using the #supportedLocales directive:
<ModulePrefs
title="__MSG_gadget.introduction.title__"
directory_title="__MSG_gadget.introduction.title__"
description="__MSG_gadget.introduction.description__">
<Require feature="dynamic-height"/>
<Require feature="settitle"/>
#supportedLocales("gadget.introduction")
</ModulePrefs>
At run time, the above section of the gadget XML will be replaced with the following:
<ModulePrefs
title="__MSG_gadget.introduction.title__"
directory_title="__MSG_gadget.introduction.title__"
description="__MSG_gadget.introduction.description__">
<Require feature="dynamic-height"/>
<Require feature="settitle"/>
<Locale
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/ALL_ALL.xml"/>
<Locale lang="fr" country="FR"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/fr_FR.xml"/>
<Locale lang="de" country="DE"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/de_DE.xml"/>
<Locale lang="pt" country="BR"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/pt_BR.xml"/>
<Locale lang="it" country="IT"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/it_IT.xml"/>
<Locale lang="de" country="CH"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/de_CH.xml"/>
<Locale lang="en" country="US"
messages="http://myhost.com:port/myapp/rest/gadgets/1.0/msg/gadget.introduction/en_US.xml"/>
</ModulePrefs>
RELATED TOPICS
Creating your Gadget XML Specification
Writing an Atlassian Gadget
Gadget Developer Documentation
Using Web Resources in your Gadget
The Atlassian Gadgets framework allows you to specify #-directives in your gadget specification XML file that will be replaced by generated
content at run time. These #-directives are provided by the Atlassian Gadget Publisher plugin. They work for any gadget that is provided as a
plugin in an Atlassian application. The #-directives do not work for gadgets that are served from an external web server.
#-directives are sometimes also called 'macros' or 'pseudo-macros'.
You can use these #-directives to specify web resources needed by your gadget.
On this page:
#requireResource and #includeResources Directives
#requireResource and #includeResources Directives
The #requireResource and #includeResources directives work with the WebResourceManager as used in JIRA (see JIRA web
resources), Confluence (see Confluence web resources) and other Atlassian applications. In turn, the WebResourceManager uses the Web
Resource Plugin Module type defined in the Atlassian Plugin Framework.
The #-directives correspond directly to the requireResource and includeResources methods in WebResourceManager.
You can include multiple #requireResource directives.
The gadget processor proceeds as follows:
When the gadget processor finds a #requireResource directive, it adds the specified resource to a list.
When the gadget processor finds a #includeResources directive, it processes the list of web resources:
First it resolves dependencies transitively (since web resources can depend on other web resource modules, potentially in
another plugin, which can themselves depend on other web resource modules, etc).
Then it eliminates any duplicates from the fully resolved list.
For example, if my gadget has both #requireResource("com.atlassian.gadgets:common-resources") and
#requireResource("com.atlassian.gadgets.mygadget:mygadget-resources"), and both of those have a dependency on
com.atlassian.auiplugin:ajs, the gadget processor will only include AJS once.
Parent Element: <Content>
Format of #requireResource:
#requireResource("plugin.key:module-key")
Each #requireResource directive names the complete module key (plugin.key:module-key) for a web-resource plugin module.
Format of #includeResources:
#includeResources()
Example:
Here is a snippet of gadget XML using the #requireResource directive to include the Atlassian Gadgets JavaScript framework, as used in
JIRA 4.0 (see Using the Atlassian Gadgets JavaScript Framework for details, including how to use it if you are not writing a gadget for JIRA
4.0):
<Content type="html">
<![CDATA[
#requireResource("com.atlassian.jira.gadgets:common")
#includeResources()
<div id="intro-content">
Hello, world
</div>
]]>
</Content>
At run time, the above section of the gadget XML will be replaced with the following:
<Content type="html">
<![CDATA[
<link type="text/css" rel="stylesheet"
href="http://myhost.com:port/myapp/s/448/1/1.1.7/_/download/batch/com.atlassian.auiplugin:ajs/com.atlassian.auiplug
media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet"
href="http://myhost.com:port/myapp/s/448/1/1.1.7/_/download/batch/com.atlassian.auiplugin:ajs/com.atlassian.auiplug
media="all">
<![endif]-->
<script type="text/javascript"
src="http://myhost.com:port/myapp/s/448/1/1.1.7/_/download/batch/com.atlassian.auiplugin:ajs/com.atlassian.auiplugi
></script>
<script type="text/javascript"
src="http://myhost.com:port/myapp/s/448/1/4.0.0/_/download/batch/com.atlassian.jira.gadgets:common/com.atlassian.ji
></script>
<link type="text/css" rel="stylesheet"
href="http://myhost.com:port/myapp/s/448/1/4.0.0/_/download/batch/com.atlassian.jira.gadgets:common/com.atlassian.j
media="all"/>
<div id="intro-content">
Hello, world
</div>
]]>
</Content>
RELATED TOPICS
Creating your Gadget XML Specification
Writing an Atlassian Gadget
Gadget Developer Documentation
Using Atlassian REST APIs in your Gadget
In the gadgets world, the UI is rendered entirely using HTML and JavaScript (on the dashboard server). To get dynamic data into the gadget,
you will make Ajax calls using makeRequest back to the originating server.
Why a special API for making requests? When we render gadgets, even if the gadget specification is coming from your server out there, it is
pulled into the dashboard server and parsed and rendered into HTML on the dashboard server. So your JavaScript can only talk to the server
where the dashboard is running. The makeRequest call will proxy back (in a process that is called 'phoning home') to the originating server
to request data, using one of the following:
The REST APIs that the application already supports.
A custom servlet that you build in a plugin for that product.
A custom REST plugin module that is built into the Atlassian Gadgets framework. This is the recommended option.
Providing User Authentication for Gadgets
Documentation under development
This page is an overview of user authentication in gadgets. There is another topic on using the authentication mechanism provided by the
Atlassian Gadgets JavaScript Framework.
To cover:
OAuth
Trusted apps
Other forms
Introduction to OAuth
The central principle behind the OAuth protocol is:
If you want a client program to access a server somewhere, there should be a more secure way than asking the user to enter their username
and password into the client program which then sends it to the server. OAuth provides another way to authenticate, using secure tokens
passed between two servers.
For example, if a user puts a JIRA Issues gadget onto their iGoogle page, they should not need to enter their JIRA username and password
into iGoogle.
RELATED TOPICS
Using Authentication in your Gadget
Using the Atlassian Gadgets JavaScript Framework
Using the Atlassian Gadgets JavaScript Framework
Available:
Atlassian Gadgets 2.0 and later.
(The Atlassian Gadgets JavaScript Framework was not part of Atlassian Gadgets 1.0.x. It was available only
within JIRA 4.0.x, as part of the JIRA project.)
This document assumes that you are familiar with (or have the documentation available for) writing gadgets and you have read Writing an
Atlassian Gadget.
Using the Atlassian Gadgets JavaScript Framework is the preferred and recommended way of developing gadgets for Atlassian applications.
On this page:
Introduction
Using the Framework
Example Gadgets
Introduction
During development of our own gadgets, we realised there were a lot of common requirements and functionality between gadgets. This led to
the development of the Atlassian Gadgets JavaScript Framework. This framework is the basis of most of the gadgets developed at Atlassian.
Terminology: On this page and its child pages,
when we refer to the 'framework', we mean the Atlassian Gadgets JavaScript Framework.
when we refer to a 'gadget', we mean a gadget JavaScript object.
Feature overview:
Authentication
Brokers a Trusted Applications connection if available and required
Brokers an OAuth connection if available and required
View Helpers
Automatic reloading of a gadget based on a time interval
Automatic reloading of a gadget on browser window resize
Automatic gadget resizing on browser window resize
Parallel Ajax resource loading for the view
Configuration
Permission-based gadget configuration
Configuration screen display on initial gadget load
Complex configuration form building
Validation of configuration
Inline error display
Saving of parameters
Parallel Ajax resource loading for configuration form
jQuery-style remoting
A wrapper over gadgets.io.makeRequest supplying a cleaner and more common interface for Ajax calls
Cookie storage
Cookie storage and retrieval on a gadget by gadget basis
Performance
Conversion of proxied remote calls into direct calls if possible
Common styling
Loading of screens, standard icons, common CSS
Using the Framework
These examples assume that you are familiar with the gadget XML format and Atlassian's customisations to it.
Here is a basic gadget specification using the Atlassian Gadgets JavaScript Framework:
The lines of interest are:
1. This includes all required JavaScript and CSS resources needed to use the framework. See Using Web Resources in your Gadget.
The path to the Atlassian Gadgets JavaScript Framework is as follows:
In Atlassian Gadgets 1.0.x, the JavaScript framework is available in JIRA only and is not part of the Atlassian Gadgets
framework. The path in JIRA 4.0.x is:
#requireResource("com.atlassian.jira.gadgets:common").
In Atlassian Gadgets 2.0 and later, the JavaScript framework has been extracted from JIRA and made part of the Gadgets
framework. The path is:
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
2. This constructs the gadget object and initialises it with the passed in options.
3. The framework needs access to the base URL, so we pass it in. See Using Substitution Variables and Directives in your Gadget.
4. This initialises the view.
Example Gadgets
See the sample OAuth gadget for a simple example of how to use the JavaScript framework.
RELATED TOPICS
Gadget Object API
Creating a Gadget JavaScript Object
Field Definitions
REST Resource for Validating Gadget Configuration
Gadget Developers' JavaScript Cookbook
Adding a Chart to the Issue Navigator
Adding a Reload Option to your Gadget
Adding Something to your Gadget Footer
Adjusting the Gadget Height when the Window is Resized
Making Ajax Calls
Making your Gadget Reload when Resized
Restricting Edit Permissions on your Gadget Preferences
Showing the Config Screen on Initial Load Only
Specifying Required Features for the Framework
Specifying Required Resources for the Framework
Theming your Gadget Dynamically
Using Authentication in your Gadget
Copy of Using Authentication in your Gadget
Using Cookies in your Gadget
Using Special UserPrefs for the Framework
Including Features into your Gadget
Using Web Resources in your Gadget
Writing an Atlassian Gadget
Gadget Developer Documentation
Gadget Object API
Available:
Atlassian Gadgets 2.0 and later.
(The Atlassian Gadgets JavaScript Framework was not part of Atlassian Gadgets 1.0.x. It was available only
within JIRA 4.0.x, as part of the JIRA project.)
Changed:
In Atlassian Gadgets 2.0.6 and later, the usePopup parameter is available in showMessage.
This page describes the methods available in each type of gadget JavaScript object. This page is part of the documentation on the Atlassian
Gadgets JavaScript Framework.
On this page:
Overview
Standard Gadget
Configured Gadget
Configurable Gadget
Overview
Please refer to Creating a Gadget JavaScript Object for details on constructing a gadget object. The methods provided on this page can be
called not only on the constructed object, but also from any method provided in the construction configs. All methods passed in as config
parameters (e.g. the view template, the config descriptor, ...) are run in the scope of the gadget itself. Therefore, this refers to the gadget
and any of the following methods can be called on this.
Under the hood, the constructor method AJS.Gadget(...) is a factory method that constructs a specific type of gadget depending on the
config parameters passed in. The three kinds of gadgets are:
Standard
Configured (inherits all of the methods from Standard Gadget)
Configurable (inherits all of the methods from Configured Gadget)
Each type is described below.
Standard Gadget
A Standard Gadget is constructed when a view parameter is passed in but no config parameter. This is useful when no configuration is
needed for the gadget. An example is the Quick Issue Create gadget in JIRA.
All other gadget types extend the Standard Gadget type.
return {
showMessage: function (type, msg, dismissible){},
savePref: function (name, value){},
database. */
setViewMode: function (){},
view. */
getViewMode: function (){},
string. For example "Canvas". */
getBaseUrl: function (){},
for jira. */
getPrefs: function (){},
getPref: function (name){},
name */
getPrefArray: function (name){},
getMsg: function (key){},
getGadget: function (){},
all gadget html (jQuery Object) */
resize: function (){},
showLoading: function (){},
hideLoading: function (){},
createCookie: function (name, value, days){},
this gadget. */
readCookie: function (name){},
value */
eraseCookie: function (name){}
};
/* Displays a message in dialogue box. */
/* Saves user preferences locally and to the
/* Toggles class of gadget to the specified
/* Returns the current view mode as a
/* Helper function to get the context path
/* Gets user preference object. */
/* Some sugar for getting a preference by
/* Retrieves a user pref array */
/* Gets the i18n String */
/* Gets the gadget object, wrapper div for
/*
/*
/*
/*
Resizes iframe to fit content */
Shows loading indicator */
Hides loading indicator */
Stores a value into a cookie, unique to
/* Retrieves a previously stored cookie
/* Removes a cookie value */
showMessage
Displays a message in a dialogue box.
showMessage: function (type, msg, dismissible, usePopup) {}
Where:
type — (String.) Style of message. Options include "error, warning, info".
msg — (String, Object.) An HTML string or jQuery object containing message.
dismissible — (Boolean.) If set to false, no cancel button will be available.
usePopup — (Boolean.) If set to false, an AUI Dialog is used (otherwise defaults to AUI Message). Available since Atlassian
Gadgets 2.0.6.
savePref
Saves user preferences locally and to the database. In order to persist these values and have them available when gadget is reloaded, the
setprefs feature must be declared as required in the gadget XML specification.
savePref: function (name, value) {}
Where:
name — (String.) Name of preference to save.
value - (String, Array.) Value (or values) to save to the database.
setViewMode
Toggles the class of the gadget to the specified view. This class is used to style the view accordingly.
setViewMode: function (mode) {}
Where:
mode — The class to toggle on the gadget.
getViewMode
Returns the current view mode as a string. For example "Canvas".
getViewMode: function () {}
getBaseUrl
Helper function to get the context path for JIRA. Necessary for remote requests.
getBaseUrl: function () {}
getPrefs
Gets user preference object.
getPrefs: function () {}
getPref
Gets a preference by name.
getPref: function (name) {}
Where:
name — The name of the preference to retrieve.
getPrefArray
Retrieves a user preference array.
getPrefArray: function (name){}
Where:
name — The name of the preference array to retrieve.
getMsg
Gets the i18n string from the included language bundles. Returns the key if it does not exist.
getMsg: function (key){}
Where:
key — The key of the message to retrieve.
getGadget
Gets the gadget object, wrapper div for all gadget HTML (jQuery object).
getGadget: function (){}
resize
Resizes the iframe to fit the content.
resize: function (){}
showLoading
Shows an indicator that the gadget is loading.
showLoading: function (){}
hideLoading
Hides the loading indicator.
hideLoading: function (){}
createCookie
Stores a value in a cookie, unique to this gadget.
Use cookies with caution, so that the browser does not create too many cookies. They are necessary if you need to store a value for the
current user rather than for the gadget. Where possible, use UserPrefs instead. UserPrefs will store values for the gadget, not the user.
createCookie: function (name, value, days){}
Where:
name — The name (key) of the cookie to store.
value — The value to store in the cookie.
days — The number of days to keep the cookie active.
readCookie
Retrieve a previously stored cookie value.
readCookie: function (name){}
Where:
name — The name of the cookie value to retrieve.
eraseCookie
Removes a cookie value.
eraseCookie: function (name){}
Where:
name — The name of the cookie value to erase.
Configured Gadget
A Configured Gadget is constructed when view and config parameters are passed in but the current user does not have permission to edit
the gadget's preferences. The gadget contains a view and footer.
This gadget has all of the same methods as a Standard Gadget plus the following:
return AJS.$.extend(getStandardInterface(), {
getView: function(){},
/* Gets the view object, wrapper div for all view html
(jQuery Object) */
showView: function(refresh){},
/* Display the view */
getFooter: function(){}
/* Gets the footer object, wrapper div for all footer html
(jQuery Object) */
});
getView
Gets the view object, wrapper div for all view HTML (jQuery object). This object is a div with the class of "view" and is contained within
the object returned from getGadget().
getView: function(){}
showView
Displays the view. When refreshing content, the view template is called. If not refreshing content, this method simply displays the currently
rendered view.
showView: function(refresh){}
Where:
refresh — Specifies whether or not to refresh the view content.
getFooter
Gets the footer object, wrapper div for all footer HTML (jQuery Object). This object is a JQuery wrapped div with the class of "footer". It
is contained within the object returned from getGadget() and is displayed underneath the view.
getFooter: function(){}
Configurable Gadget
A Configurable Gadget is constructed when view and config parameters are passed in and the current user has permission to edit the
gadget's preferences. The gadget contains a view, a footer and a configuration screen.
This gadget inherits all of the methods from Configured Gadget plus the following:
return AJS.$.extend(getConfiguredInterface(), {
showConfig: function(){},
/* Displays the configuration screen */
getConfig: function(){}
/* Gets the config object, wrapper div for all config html (jQuery
Object) */
});
showConfig
Displays the configuration screen with all fields defined during construction.
showConfig: function(){}
getConfig
Gets the config form object, wrapper div for all config HTML (jQuery Object). It is contained within the object returned from getGadget().
getConfig: function(){}
RELATED TOPICS
Using the Atlassian Gadgets JavaScript Framework
Writing an Atlassian Gadget
Gadget Developer Documentation
Creating a Gadget JavaScript Object
This page tells you how to create a gadget using the Atlassian Gadgets JavaScript Framework.
On this page:
High-Level Format for Creating a Gadget
Authentication
Configuration Form
Ajax Options
Configuration Descriptor
Configuration Fields
View
View Template Function
High-Level Format for Creating a Gadget
The framework uses a declarative approach in terms of configuration. View, configuration and authorisation parameters are passed into the
constructor and used to configure the gadget. See Gadget Object API for methods available on the gadget object.
The top-level options are:
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__",
useOauth: ...,
config: ...,
view:...
});
Where:
baseUrl — A required option used to pass the base URL to the framework. The framework uses this URL for prefixing relative Ajax
requests and also makes it available from gadget.getBaseUrl() and AJS.gadget.getBaseUrl().
useOauth — An optional parameter that is used to configure the type of authentication used. Here you must provide a URL that
requires authentication. Typically we use "/rest/gadget/1.0/currentUser". The framework will then try to broker an
authenticated connection in the following order:
1. Current session (a gadget being served locally, e.g. JIRA displaying a JIRA gadget), then
2. A Trusted Applications connection, then
3. OAuth. A gadget being served in a non-Atlassian container will typically use OAuth.
config — You can use this optional parameter to define the configuration form. If this parameter is not defined, it is assumed that the
gadget has no configuration options. Please note that this is not the built-in Opensocial Gadget configuration screen. The latter did
not meet our needs so we decided to implement our own. See below.
view — This object defines the view to display. See below.
Authentication
The framework will automatically try to broker an authenticated connection to the server, based on the URL provided in the useOauth
configuration option described above. If the value passed in is "always", the framework will always try and use OAuth. If the value passed
in is a URL, the framework will determine the best method of invoking that URL. The URL must not allow anonymous access. JIRA currently
provides the following REST resource:
/rest/gadget/1.0/currentUser
The framework tries to connect to the server in the following order:
1. Local — We can determine whether the gadget is being served locally (e.g. JIRA serving out a JIRA gadget) and then we can just
use the local browser to talk to the server. This is the most efficient method of communication as no proxies are used.
2. Trusted Applications — If a successful request returns from the supplied resource when no OAuth token is passed, it must be a
trusted application. We rely on the container server to use its Trusted Applications connection to the remote server for
authentication.
3. OAuth - If the previous two methods fail, we fall back to OAuth.
More: Using Authentication in your Gadget
Configuration Form
Early on in our Gadget development, we realised that the OpenSocial gadgets' mechanism for creating configuration forms was not going to
meet our needs. The fields must all be known beforehand, options are static and fields cannot be manipulated programatically. OpenSocial
also only supports very basic fields. Our framework offers all the options available in the Opensocial Gadget framework for creating a
configuration form. In addition, our framework allows for Ajax populated lists, custom fields and even dynamically included fields.
Typically, when loaded, a gadget will show a config screen first, then the normal gadget view. The user can choose to view it in canvas view
if defined.
In order to take full advantage of the features in the framework, you should include the following in your gadget XML:
<Require feature="setprefs" />
<Require feature="views" />
<Require feature="dynamic-height" />
Where:
setprefs — This is required to persist user preferences.
views — This is used to determine whether the current user can edit the preferences or not. Please note that this is an
Atlassian-specific extension to the feature and will not work in other containers. The edit button will always be shown in other
containers.
dynamic-height — Provides dynamic height adjustment in the config screen, view creation and on resize.
The config object consists of two parts: Ajax option definitions and a descriptor. When the form is generated, the Ajax options are retrieved
and then fed into the descriptor which then returns an object fully defining the configuration form. The framework will then render the form.
When the form is submitted, the form will use the passed in validation URL to validate the form and if successful, will then save the
preferences to the server. If validation fails, the form will display the errors inline.
All fields on the configuration form will be persisted as UserPrefs against the gadget.
...
config: {
descriptor: function(){...},
args: {Function, Array}
},
...
Where:
descriptor — This function returns a new Configuration Descriptor
args — Either an array of objects or a function that returns one. The objects in this array have two keys:
(String) key — Name of key that will be used to access the data from within the template.
(Object) ajaxOptions — Set of request options to retrieve data from remote resource. Options are available here. If a String
is used, it will just retrieve the REST resource assuming it is JSON.
Ajax Options
This can either be an array of options to retrieve, or a function that returns a similar array.
...
args: [
{
key: "key to access options by",
ajaxOptions: "/rest/gadget/1.0/projects" /* this can also be a more complex JQuery style
remote call */
},
... more options to retrieve
]
...
Where:
key — The descriptor will be able to access the results of the Ajax call via this key, e.g. args.key.
ajaxOptions — If this is a string, the framework assumes it is the URL to a REST resource returning JSON. However, this can be a
more complex jQuery-style remote call definition. Options are available here.
jQuery style remote Ajax options
...
args: [
{
key: "project",
ajaxOptions: {
url: "/rest/gadget/1.0/projects",
data: {
restrictToPermission: "create"
},
type: "POST"
}
},
... more options to retrieve
]
...
Note: This is just a fictitious REST resource. The example will not work.
Configuration Descriptor
The configuration descriptor is a function that returns an object defining the configuration form. After the Ajax options have been retrieved,
they are passed into the function to get the object that defines the form.
The function is called within the scope of the gadget. Hence this refers to the current gadget object.
...
descriptor: function(args){
/* This is called within the scope of the current gadget. "this" refers to the current gadget
*/
return {
action: "validation url", /* A url to validate the form against */
theme: "", /* The layout of the form - "top-label" or "long-label" */
fields:[
{
/* Field descriptor */
},
... more fields
]
};
},
...
Where:
args — This is an object populated by the results of the Ajax options defined in the args parameter of the config object. If you
retrieve a list of projects via Ajax, this list can be accessed via: args.projects
action — This is a URL pointing to a REST resource that will validate the form and return appropriate errors if the form contains
invalid data. Please see the information about the format for the REST resource validating gadget configuration for the structure and
return codes of the response.
theme — This tells the form how to lay itself out. There are two possible values:
"top-label" — This displays the field label above the field. Useful for narrow forms.
"long-label" — This displays the label on the same line as the field. Better suited to forms with a lot of width available.
fields — This is an array of field objects.
More: Theming your Gadget Dynamically
Configuration Fields
Configuration forms are made up of list of fields. Typically, these fields relate to UserPref fields defined in the gadget XML. We usually define
our UserPrefs in the XML as hidden UserPrefs. This will ensure that the field will not appear in the OpenSocial gadget configuration form.
E.g.
<UserPref name="project" datatype="hidden" />
We support the following types of fields (details are on the Field Definitions page):
Hidden fields — A hidden input area on the form whose value is passed back to the server during validation and preference saving.
Text input — A single line text input.
Text area — A text area for accepting larger text inputs.
Select fields — A simple selection list that displays a list of options. It is possible to display a list of options retrieved from a REST
resource.
Multi-select fields — A multi-select field where it is possible to select multiple values. It is possible to display a list of options retrieved
from a REST resource.
Radio button group — A set of radio buttons for selecting unique values. It is possible to display a list of options retrieved from a
REST resource.
Check box group — A set of check boxes to select multiple values. It is possible to display a list of options retrieved from a REST
resource.
Custom fields — A user defined field. This allows users to insert arbitrary HTML into the form.
Callback builder — An empty <div/> is inserted into the form. After form creation, a callback handler is called passing in the jQuery
wrapped div. This is the most powerful field creation technique and can be used to build highly interactive fields.
More:
Field Definitions
Showing the Config Screen on Initial Load Only
Specifying Required Resources for the Framework
View
This object defines the view to display, as shown in the high level overview above.
config: {...},
view: {
enableReload: true,
onResizeReload: true,
onResizeAdjustHeight: false,
template: function (args) {},
args: [{
key: "chart",
ajaxOptions: {...}
}]
}
Where:
enableReload — (Optional.) Adds a reload icon to the bottom of the gadget and adds a reload period option to the configuration
form. The gadget will redraw the view every X minutes.
onResizeReload — (Optional.) When the browser window resizes or the layout changes, the gadget redraws the view. This is used
in our chart gadgets so that the chart image can be regenerated to size and granularity.
onResizeAdjustHeight — (Optional.) When the browser window resizes or the layout changes, gadget.adjustHeight() is
called to ensure that if any lines changed their wrapping the gadget height will adjust accordingly. You must include the
dynamic-height feature for this to work.
template — A function that is responsible for creating the view. See below.
args — Either an array of objects or function that returns one. The results of these remote calls are passed in to the template during
rendering.
key — Name of the key that will be used to access the data from within the template.
ajaxOptions — Set of request options to retrieve data from a remote resource. Options are jQuery Ajax options.
View Template Function
The template function is responsible for rendering the gadget's view. The function is run within the scope of the gadget so 'this' refers to
the gadget. See the Gadget Object API for the methods available.
The template creates HTML using jQuery. It does not include styling. Styling is done later via CSS.
The function takes one argument – args – a map containing the response from the Ajax calls. This map is keyed by the specified key.
The function must be able to be called multiple times for reloading and resizing.
Example:
view: {
enableReload: true,
onResizeAdjustHeight: true,
template: function (args) {
var gadget = this;
var filters = args.favFilters.filters;
if (!filters){
gadget.getView().removeClass("loading").html("<p>__MSG_gadget.favourite.filters.no.favourites__</p>");
} else {
var list = AJS.$("<ul/>").attr("id", "filter-list");
AJS.$(filters).each(function(){
list.append(
AJS.$("<li/>").append(
AJS.$("<div/>").addClass("filter-name").append(
AJS.$("<a/>").attr({
target: "_parent",
title: gadgets.util.escapeString(this.description),
href:
"__ATLASSIAN_BASE_URL__/secure/IssueNavigator.jspa?mode=hide&requestId=" + this.value
}).text(this.label)
)
).append(
AJS.$("<div/>").addClass("filter-count").text(this.count)
).click(function () {
if (window.parent){
window.parent.location =
"__ATLASSIAN_BASE_URL__/secure/IssueNavigator.jspa?mode=hide&requestId=" + this.value;
} else {
window.location =
"__ATLASSIAN_BASE_URL__/secure/IssueNavigator.jspa?mode=hide&requestId=" + this.value;
}
})
);
});
gadget.getView().html(list);
}
},
args: [{
key: "favFilters",
ajaxOptions: function () {
return {
url: "/rest/gadget/1.0/favfilters",
data: {
showCounts : this.getPref("showCounts")
}
};
}
}]
}
RELATED TOPICS
Using the Atlassian Gadgets JavaScript Framework
Writing an Atlassian Gadget
Gadget Developer Documentation
Field Definitions
This page gives more detail about the field types that were introduced in Creating a Gadget JavaScript Object.
On this page:
Hidden Fields
Text Input
Text Area
Select
Multi Select
Radio Button Group
Checkbox Group
Custom Field
Callback Builder
Hidden Fields
Sometimes you want to pass values back to the server from a form submission, but you do not want the user to be able to change those
values. You can use hidden fields to achieve this.
The following code defines a hidden field:
fields: [
{
userpref: "isConfigured",
type: "hidden",
value: "true" /* This example is hard coded but it could be dynamically
generated or retrieved from the gadget prefs.*/
},
... /* Other fields */
]
Where:
userpref — The name of the field. Should be the name of the UserPref to save.
type — Use "hidden" to specify that this field is hidden.
value — The value that will be passed back to the server for validation and will then be saved.
Text Input
This field type will be displayed as a simple text field. If the the type attribute is not defined, the field will be of this type by default.
fields: [
{
id: "numToDisplay",
userpref: "numToDisplay",
class: "numField"
label: gadget.getMsg("gadget.common.num.label"),
description: gadget.getMsg("gadget.common.num.description"),
type: "text",
value: gadget.getPref("numToDisplay")
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this field. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this field. If omitted, will default to type.
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — (Optional.) If the value is "text" or omitted, a text field (i.e. the type discussed in this paragraph) is rendered.
value — (Optional.) The initial value of the field. If this is a UserPref, we usually populate it with the UserPref value.
Text Area
This field type creates a text input area in the form, used for large text inputs.
fields: [
{
id: "textToDisplay",
userpref: "textToDisplay",
class: "textBox"
label: gadget.getMsg("gadget.common.display.text.label"),
description: gadget.getMsg("gadget.common.display.text.description"),
type: "textarea",
value: gadget.getPref("textToDisplay")
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this field. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this field.
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — Value must be "textarea" for this type of field.
value — (Optional.) The initial value of the field. If this is a UserPref, we usually populate it with the UserPref value.
Select
This field type is a simple selection list. As the AJAX options have been retrieved and are available during the creation of the field decscriptor,
it is trivial to use them as options for the selection list. The results can be used raw or transformed.
fields: [
{
id: "cumulative-field",
class: "cumulative-select-list",
userpref: "isCumulative",
label: gadget.getMsg("gadget.common.cumulative.label"),
description:gadget.getMsg("gadget.common.cumulative.description"),
type: "select",
selected: gadget.getPref("isCumulative"),
options:[
{ /* These options are hard-coded but could easily be the results of an AJAX call
(E.g. args.projects) or be calculated at run time (E.g. the next three days) */
label:gadget.getMsg("gadget.common.yes"),
value:"true"
},
{
label:gadget.getMsg("gadget.common.no"),
value:"false"
}
]
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this field. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this field. Defaults to "select".
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — Value must be "select" for this type of field.
selected — (Optional.) The value of initially selected option. If this is a UserPref, we usually populate it with the UserPref value.
options – An array of option pairs or groups.
An option is defined as:
{
id : "option-id",
label: "A human readable label",
value: "option-value",
selected: true
}
Where:
id — (Optional.) The id of the option.
label — The displayable label for the option.
value — The value to save if this option is selected.
selected — (Optional.) Specifies whether or not to initially select this option. If only one option can be selected (selection list or radio
group) it is more convenient to specify the selected value on the field definition.
Option groups are used in the following example:
fields: [
{
userpref: "groupedOptions",
label: gadget.getMsg("gadget.common.grouped.label"),
type: "select",
selected: gadget.getPref("groupedOptions"),
options:[
{
group: {
label: "First Option Group",
options: [
{
label: "First Group -> First Option",
value: "group-1_opt-1",
},
{
label: "First Group -> Second Option",
value: "group-1_opt-2",
}
]
}
},
{ /* You can mix groups and non-group options */
label:"No Group Options",
value:"group-N/A_opt-1"
},
{
group: {
label: "Second Option Group",
options: [
{
label: "Second Group -> First Option",
value: "group-2_opt-1",
}
]
}
}
]
},
... /* Other fields */
]
Where:
group — An object containing the sub-options.
group.label — The label for the option group.
group.options — The options to display under the option group.
Multi Select
This field type produces a multi-select input value.
fields: [
{
id: "version-field",
class: "multiVersionField",
userpref: "selectedVersions",
label: gadget.getMsg("gadget.common.versions.label"),
description:gadget.getMsg("gadget.common.versions.description"),
type: "multiselect",
selected: gadget.getPref("selectedVersions"), /* Only use this if you only want value
selected.
Otherwise specify selection state on the
option itself */
options:[ /* See Select Field for valid options */]
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this field. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this field. Defaults to "multi-select".
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — Value must be "multiselect" for this type of field.
selected — (Optional.) The value of initially selected option. Only use this if you only want a single value selected. Otherwise specify
selection state on the option itself.
options — An array of options pairs or groups. See the GADGETS:Select field type (above) for valid options.
Radio Button Group
This field type produces a group of radio buttons for selecting a unique value from a list of choices.
fields: [
{
id: "security-level",
class: "security-radio",
userpref: "securityLevel",
label: gadget.getMsg("gadget.common.security.label"),
description:gadget.getMsg("gadget.common.security.description"),
type: "radio",
selected: gadget.getPref("securityLevel"),
options:[
{ /* See Select Field for valid options */
label: "Publicly Available",
value:"public"
},
{
label:"Private",
value:"private"
}
]
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this fieldset. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this fieldset.
label — The label to display next to the fieldset.
description — (Optional.) The description of the field.
type — Value must be "radio" for this type of field.
selected — (Optional.) The value of the option to be selected initially. If this is a UserPref, we usually populate it with the UserPref
value.
options — An Array of options pairs or groups. See the GADGETS:Select field type (above) for valid options.
Checkbox Group
This field type produces a group of checkboxes for selecting multiple values.
fields: [
{
id: "group-select",
class: "group-selector-checkboxes",
userpref: "selectedGroups",
label: gadget.getMsg("gadget.common.groups.label"),
description:gadget.getMsg("gadget.common.groups.description"),
type: "checkbox",
options:[
{ /* See Select Field for valid options */
id: "group-users",
label: "Users",
value: "users"
},
{
id: "group-devs",
label: "Developers",
value: "developers",
selected : true
},
{
id: "group-admins",
label: "Administrators",
value: "admins",
selected : true
}
]
},
... /* Other fields */
]
Where:
id — (Optional.) The HTML id to give this fieldset. Defaults to the value of the userpref field.
userpref — The name of the field. Should be the name of the UserPref to save.
class — (Optional.) The HTML class to apply to this fieldset.
label — The label to display next to the fieldset.
description — (Optional.) The description of the field.
type — Value must be "checkbox" for this type of field.
selected — (Optional.) The value of the option to be selected initially. Only use this if you only want a single value selected.
Otherwise specify the selection state on the option itself.
options — An Array of options pairs or groups. See the GADGETS:Select field type (above) for valid options.
Custom Field
This field type simply injects the string into the form as HTML.
fields: [
{
label: gadget.getMsg("gadget.common.groups.label"),
description:gadget.getMsg("gadget.common.groups.description"),
type: "custom",
template: function(){
/* Returned string is injected into form */
return "<div>An example of a custom field</div>";
}
},
... /* Other fields */
]
Where:
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — Value must be "custom" for this type of field.
template – A function that returns a string to inject into the form.
Callback Builder
This is the most powerful and flexible type of field for configuration. The callback enables you to construct any HTML and attach event
listeners to it.
fields: [
{
id: "my-callback-field",
label: gadget.getMsg("gadget.common.builder.label"),
description:gadget.getMsg("gadget.common.builder.description"),
type: "callbackBuilder",
callback: function(parentDiv){
parentDiv.append(
AJS.$("<input/>").attr({
id: "call-back-hidden-field",
type: "hidden",
name: userpref
}).val(gadget.getPref("myCallback))
);
}
},
... /* Other fields */
]
Where:
id — The id given to the div that is passed into the builder.
label — The label to display next to the field.
description — (Optional.) The description of the field.
type — Value must be "callbackBuilder" for this type of field.
callback — A function that takes in a JQuery wrapped div. You can then manipulate the contents of that div and attach event
handlers, e.g. click handlers.
RELATED TOPICS
Using the Atlassian Gadgets JavaScript Framework
Writing an Atlassian Gadget
Gadget Developer Documentation
REST Resource for Validating Gadget Configuration
The REST resource that is used to validate the configuration parameters of a gadget should simply return a 200 OK status if the parameters
are valid.
If the configuration is not valid, the REST resource should return a 400 Bad Request status with a JSON format body containing error
messages.
Error messages may either be general (e.g. pointing out an inter-field consistency problem) or specific to the value of a particular field.
{
"errorMessages":
{
"start.date.before.end.date",
"some.other.error"
}
"errors":
{
"field": "bugzillaUrl", "error": "gadget.bugzilla.invalid.url"
}
}
Here's an example of Java JAXB annotated classes which produce suitable JSON:
@XmlRootElement
public class ErrorCollection
{
/**
* Generic error messages
*/
@XmlElement
private Collection<String> errorMessages = new ArrayList<String>();
/**
* Errors specific to a certain field.
*/
@XmlElement
private Collection<ValidationError> errors = new ArrayList<ValidationError>();
...
}
@XmlRootElement
public class ValidationError
{
// The field the error relates to
@XmlElement
private String field;
// The Error key...
@XmlElement
private String error;
@XmlElement
private Collection<String> params;
...
}
RELATED TOPICS
Creating a Gadget JavaScript Object
Gadget Developers' JavaScript Cookbook
Terminology: On this page and its child pages,
when we refer to the 'framework', we mean the Atlassian Gadgets JavaScript Framework.
when we refer to a 'gadget', we mean a gadget JavaScript object.
Here is a list of all entries in the cookbook, plus the first few lines of content. Click a link to see the full text for each entry.
Adding a Chart to the Issue Navigator
Place the gadget in the 'JIRA' and 'Charts' categories, include 2 userprefs and change the gadget configuration field:
Adding a Reload Option to your Gadget
This will add a reload icon to the footer of the gadget and an auto-reload option to the config screen:
Adding Something to your Gadget Footer
Use the following code in your view template function:
Adjusting the Gadget Height when the Window is Resized
Enable the onResizeAdjustHeight option on the view object:
Making Ajax Calls
The framework wraps the OpenSocial gadgets.io.makeRequest method with the standard jQuery interface. You should write code as if
you were just using the jQuery interface. For example:
Making your Gadget Reload when Resized
Enable the onResizeReload option on the view object:
Restricting Edit Permissions on your Gadget Preferences
Use the framework and include the views feature:
Showing the Config Screen on Initial Load Only
# Include the isConfigured userpref defaulted to 'false':
Specifying Required Features for the Framework
In addition to our full list of features, below is a summary of the features used by the Atlassian Gadgets JavaScript Framework. It is safest
just to include all of them:
Specifying Required Resources for the Framework
The framework requires the inclusion of the following resources:
Theming your Gadget Dynamically
It is possible to have the theme dynamically adapt to the space available with some JavaScript like this:
Using Authentication in your Gadget
Specify the appropriate features as 'required' in your gadget XML, include the necessary resources in the CDATA section, and use the
useOauth parameter when constructing your gadget:
Using Cookies in your Gadget
Use the gadget object API for createCookie, readCookie and eraseCookie:
Using Special UserPrefs for the Framework
There are a couple of UserPref values that the framework can use to add functionality to the gadget:
RELATED TOPICS
Using the Atlassian Gadgets JavaScript Framework
Gadgets and Dashboards Documentation
Adding a Chart to the Issue Navigator
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I add my chart to the issue navigator view?
Place the gadget in the 'JIRA' and 'Charts' categories, include 2 userprefs and change the gadget configuration field:
1. Place the gadget in both categories: 'JIRA' and 'Charts':
<Optional feature="gadget-directory">
<Param name="categories">
JIRA
Charts
</Param>
</Optional>
2. Include the following 2 UserPrefs:
<UserPref name="isPopup" datatype="hidden" default_value="false"/>
<UserPref name="projectOrFilterId" datatype="hidden" />
3. Dynamically change the Configuration field for your gadget's Configuration form:
config: {
descriptor: function ()
{
var gadget = this;
var filterField ;
if (/^jql-/.test(gadget.getPref("projectOrFilterId")) || gadget.getPref("isPopup")
=== "true"){
// JQL has been passed in and we should place this in a hidden field
filterField =
{
userpref: "projectOrFilterId",
type: "hidden",
value: gadgets.util.unescapeString(gadget.getPref("projectOrFilterId"))
};
} else{
// Lets display the filter picker
filterField = AJS.gadget.fields.filterPicker(gadget, "projectOrFilterId");
}
return {
action: "/rest/gadget/1.0/chart/validate",
theme : "top-label",
fields: [
filterField,
{ other field }
]
};
}
}
The popup sets the 'projectOrFilterId' UserPref to the value jql-<JQL-string>. You do not want to display the filter picker.
4. Your resource should accept the UserPref projectOrFilterId and be able to deal with values of both formats:
filter-<filterId> and jql-<JQL string.
Refer to the PieChart Gadget for an example of this functionality.
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Adding a Reload Option to your Gadget
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I add an automatic reload to my gadget?
This will add a reload icon to the footer of the gadget and an auto-reload option to the config screen:
1. Include the refresh userpref defaulted to false:
<UserPref name="refresh" datatype="hidden" default_value="false" />
2. Enable reloading in the view config object:
view: {
enableReload: true,
template: ...
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Adding Something to your Gadget Footer
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I add something to the footer?
Use the following code in your view template function:
view:{
template: function(args) {
var gadget = this;
gadget.getFooter().append(
AJS.$("<div/>").text("Text for the footer");
);
}
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Adjusting the Gadget Height when the Window is Resized
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I make gadgets.window.adjustHeight() be called when the window is resized?
Enable the onResizeAdjustHeight option on the view object:
view: {
onResizeAdjustHeight: true,
template: ...
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Making Ajax Calls
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I make Ajax calls?
The framework wraps the OpenSocial gadgets.io.makeRequest method with the standard jQuery interface. You should write code as if
you were just using the jQuery interface. For example:
AJS.$.ajax({
url: "/rest/gadget/1.0/filtersAndProjects",
type: "GET",
data: ({projectsOnly : "true"}),
dataType: "json",
success: function(msg){
alert(msg);
}
});
Unlike jQuery, due to this bug, AJS.$.ajax doesn't use dataType to set an Accept header on the request, so your
endpoint must be able to determine what content type to serve from the url or parameters.
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Making your Gadget Reload when Resized
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I make the gadget reload when it is resized?
Enable the onResizeReload option on the view object:
view: {
onResizeReload: true,
template: ...
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Restricting Edit Permissions on your Gadget Preferences
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I restrict who can edit my gadget preferences?
Use the framework and include the views feature:
<Require feature="views" />
Note: This is an Atlassian-specific extension to the views feature.
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Showing the Config Screen on Initial Load Only
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I show the config screen on initial load only?
Include the isConfigured userpref defaulted to 'false' and include the nowConfigured field in your config descriptor. On first save, the
userpref will be set to true and from then on, the view screen will be shown on gadget load:
1. Include the isConfigured userpref defaulted to 'false':
<UserPref name="isConfigured" datatype="hidden" default_value="false" />
2. Include the following field in your config descriptor:
AJS.gadget.fields.nowConfigured()
3. Or, if that is not available:
{
userpref: "isConfigured",
type: "hidden",
value: "true"
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Specifying Required Features for the Framework
This page is part of the Gadget Developers' JavaScript Cookbook.
What features are required for the framework?
In addition to our full list of features, below is a summary of the features used by the Atlassian Gadgets JavaScript Framework. It is safest
just to include all of them:
Feature
Where Used
setprefs
To store gadget preferences.
views
To detect whether the user can edit the gadget preferences.
settitle
To automatically include the instance name in the title.
dynamic-height
Config screen,
View creation,
onResizeAdjustHeight
oauthpopup
Authentication.
#oauth
Authentication
auth-refresh
To automatically refresh the authentication of the gadget on a regular basis. Notes:
This feature is available in Atlassian Gadgets 1.1.3 and later versions of 1.1.x, and in 2.0.3 and all later versions.
You should use an <Optional> element to declare this feature, otherwise your gadget will not work in
containers not based on Shindig.
atlassian.util
To detect whether the gadget is rendered by the same server it fetches data from, allowing retrieval optimisations. Note:
You should use an <Optional> element to declare this feature, otherwise your gadget will not work in
non-Atlassian containers.
RELATED TOPICS
Including Features into your Gadget
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Specifying Required Resources for the Framework
This page is part of the Gadget Developers' JavaScript Cookbook.
What resources do I need to specify as required in order to use the framework?
The framework requires the inclusion of the following resources:
#requireResource("com.atlassian.jira.gadgets:common")
#includeResources()
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Theming your Gadget Dynamically
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I dynamically theme my gadget?
It is possible to have the theme dynamically adapt to the space available with some JavaScript like this:
action: ...
theme : function () {
if (gadgets.window.getViewportDimensions().width < 500){
return "top-label";
} else{
return "long-label";
}
}(),
fields: ...
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Using Authentication in your Gadget
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I use authentication in my gadget?
Specify the appropriate features as 'required' in your gadget XML, include the necessary resources in the CDATA section, and use the
useOauth parameter when constructing your gadget:
1. Specify the appropriate features as 'required' in the gadget XML:
<Require feature="oauthpopup" />
#oauth
2. Include the following resources at the beginning of the CDATA section:
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
#includeResources()
See note about the path below.
3. Construct a gadget passing the URL in the useOauth param:
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__",
useOauth: "/rest/gadget/1.0/currentUser",
...
4. Any Ajax call will now go through the authentication steps if required.For example:
AJS.$.ajax({
url: "/rest/gadget/1.0/filtersAndProjects",
type: "GET",
data: ({projectsOnly : "true"}),
dataType: "json",
success: function(msg) {
alert(msg);
}
});
Path to JavaScript Framework
The path to the Atlassian Gadgets JavaScript Framework is as follows:
In Atlassian Gadgets 1.0.x, the JavaScript framework is available in JIRA only and is not part of the Atlassian Gadgets framework.
The path in JIRA 4.0.x is:
#requireResource("com.atlassian.jira.gadgets:common").
In Atlassian Gadgets 2.0 and later, the JavaScript framework has been extracted from JIRA and made part of the Gadgets
framework. The path is:
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Copy of Using Authentication in your Gadget
This page is a DRAFT and is visible to Atlassian staff only'. At the release of Gadgets 1.1.3, the content of this page will replace its parent
page.
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I use authentication in my gadget?
Specify the appropriate features in your gadget XML, include the necessary resources in the CDATA section, and use the useOauth
parameter when constructing your gadget:
1. Specify the appropriate features as 'required' or 'optional' in the gadget XML:
<Optional feature="auth-refresh"/>
<Require feature="oauthpopup" />
#oauth
2. Include the following resources at the beginning of the CDATA section:
2.
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
#includeResources()
See note about the path below.
3. Construct a gadget passing the URL in the useOauth param:
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__",
useOauth: "/rest/gadget/1.0/currentUser",
...
4. Any Ajax call will now go through the authentication steps if required.For example:
AJS.$.ajax({
url: "/rest/gadget/1.0/filtersAndProjects",
type: "GET",
data: ({projectsOnly : "true"}),
dataType: "json",
success: function(msg) {
alert(msg);
}
});
Path to JavaScript Framework
The path to the Atlassian Gadgets JavaScript Framework is as follows:
In Atlassian Gadgets 1.0.x, the JavaScript framework is available in JIRA only and is not part of the Atlassian Gadgets framework.
The path in JIRA 4.0.x is:
#requireResource("com.atlassian.jira.gadgets:common").
In Atlassian Gadgets 2.0 and later, the JavaScript framework has been extracted from JIRA and made part of the Gadgets
framework. The path is:
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Using Cookies in your Gadget
This page is part of the Gadget Developers' JavaScript Cookbook.
How do I use cookies in my gadget?
Use the gadget object API for createCookie, readCookie and eraseCookie:
view: {
template: function(args) {
var gadget = this;
gadget.createCookie("columnOrder", "assignee", 30);
var columnOrder = gadget.readCookie("columnOrder");
gadget.eraseCookie("columnOrder");
}
}
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Using Special UserPrefs for the Framework
This page is part of the Gadget Developers' JavaScript Cookbook.
What are the special userprefs used for?
There are a couple of UserPref values that the framework can use to add functionality to the gadget:
<UserPref name="isConfigured" datatype="hidden" default_value="false" />
<UserPref name="refresh" datatype="hidden" default_value="false"/>
<UserPref name="isPopup" datatype="hidden" default_value="false"/>
Where:
isConfigured — Specifies whether the gadget has been configured. If it has not been configured, the config screen is shown. If it
has been configured, the view screen is shown.
refresh — Stores how often the gadget should automatically refresh.
isPopup — Is set by the server to determine whether the gadget is being displayed as a popup window, as opposed to inside a
dashboard.
RELATED TOPICS
Gadget Developers' JavaScript Cookbook
Using the Atlassian Gadgets JavaScript Framework
Managing Caching for your Gadget
Caching is on by default in most applications.
You can control caching as follows:
Change the global default by setting the system property with key com.atlassian.gadgets.dashboard.ignoreCache to
true or false.
Change the caching setting on a single request, regardless of the system property setting, by adding the ignoreCache parameter
to the URL, e.g. http://jira.example.com/jira/secure/DashboardV2.jspa?ignoreCache=false.
If caching is on (e.g. ignoreCache is false), your gadget specs and locale files will not update right away when they change.
RELATED TOPICS
Writing an Atlassian Gadget
[Gadgets and Dashboards Development Hub]
Gadget Containers
To display your gadget, you will need a dashboard or other OpenSocial container that supports Atlassian gadgets.
Atlassian Applications
These Atlassian applications act as containers for gadgets:
JIRA 4.0 or later – you can add a gadget to your JIRA dashboard.
Confluence 3.1 or later – you can use the Gadget macro to embed a gadget on a wiki page.
See the version matrix for more details on Atlassian application support for gadgets.
Other Applications and Websites
Gadgets that display information from Atlassian applications, such as JIRA, should be able to run on other web sites that provide OpenSocial
containers.
Atlassian support does not cover gadgets on external sites like iGoogle and Gmail
In principle, you should be able to add Atlassian gadgets to iGoogle, Gmail and other external sites that support
OpenSocial gadgets. However, these external integrations are experimental at this stage and we have encountered
problems with them. Please do have fun playing around with them, but be aware that Atlassian does not support the use of
Atlassian gadgets on iGoogle, Gmail or other external web sites. See the detailed section on gadget limitations.
Gmail.
iGoogle.
Google Apps. See blog post introducing private apps. This means that you can add gadgets to Google Apps from your
behind-the-firewall Atlassian application, such as Confluence or JIRA.
One of the other OpenSocial containers such as a Ning community like The Content Wrangler.
The Google OpenSocial Development Environment. This platform provides an Eclipse plugin that lets you develop either OpenSocial
JavaScript (gadget) client applications or OpenSocial Java client applications using OpenSocial 0.8's REST/RPC protocols, entirely
within the Eclipse development environment. See the introductory blog post.
RELATED TOPICS
Gadgets and Dashboards Documentation
Examples of Gadgets
Gadget Support
Atlassian will provide support for gadgets that are part of supported plugins. Please refer to [Atlassian supported plugins].
Atlassian support does not cover gadgets on external sites like iGoogle or Gmail. See the detailed section on gadget
limitations.
See the sample gadgets module in the AG project. The list of gadgets is in the atlassian-plugin.xml.
Atlassian Gadgets
These gadgets have been developed for use on the dashboards of Atlassian applications. Typically they allow you to view and interact with
information from an Atlassian application such as JIRA and Confluence.
Crucible Gadget Plugin — This is a plugin that you will need to install into Crucible 2.0 or later.
JIRA Issues Gadget — This comes in two varieties:
The basic version is designed to run standalone. It fetches anonymously-viewable issues from jira.atlassian.com.
You can use the Subversion XML spec file URL directly to serve the gadget, or check it out and copy the containing
directory to your own web server.
The plugin version can be checked out and built with Maven 2 (by running mvn package). The resulting JAR file at
target/jira-issues-gadget-plugin-1.0-SNAPSHOT.jar can be installed into JIRA 4.0 or later.
Other Gadgets that Work on Atlassian Dashboards
These are gadgets that we have tried on our test Dashboards and that seem to work. We do not guarantee them in any way, but they are
interesting and provide a good starting point for experimentation.
Tree Frog — This is the gadget URL that you can add directly to your dashboard.
RELATED TOPICS
Tutorials on Writing a Gadget
Gadget Developer Documentation
Gadgets and Dashboards Documentation
Tutorials on Writing a Gadget
Below are some useful tutorials on how to write a gadget:
Writing an Atlassian Gadget – Highly recommended, a tutorial written by Atlassian partner CustomWare.
Creating a Plugin Gadget for JIRA
Writing a gadget that displays the days left in a version
Writing a JQL Gadget for JIRA
Crucible Gadget Tutorial
Using the FishEye REST API to Write a Gadget to Monitor Recent Changes
Tutorial Templates
RELATED TOPICS
Plugin Tutorials
Gadget Development
Tutorial Templates
These are templates for various types of gadget tutorial. Please feel free to copy a template to a new page and base your own tutorial on it.
Feel free to depart from the template
You can start with the template and then change the sections in your own tutorial when the template is no longer useful.
The templates serve 2 purposes. The first is to make it easier for people to get started in writing a tutorial. The second is to
give all the tutorials the same overall look and feel, so that the reader gets some sense of familiarity and comfort. But the
minute the template stops being useful, anyone should feel free to dump or adapt the bits that are not useful.
Template for Plugin Gadget Tutorial
Template for Standalone Gadget Tutorial
Template for Plugin Gadget Tutorial
Please ignore this page unless you want to write a gadget tutorial
This page is just a template for tutorial developers to use when writing a new tutorial. The real tutorials are listed here:
Tutorials on Writing a Gadget.
(To the tutorial author: This is a template. You can copy the content of this page and use it to create your own gadget tutorial. When you
have finished, delete all sections that start with 'To the tutorial author' from your copy of the page. Otherwise the page will self-destruct when
you finish reading it.)
(To the tutorial author: CHOOSE ONE OF THE 3 LEVELS BELOW (beginner, intermediate or advanced), LEAVE THAT ONE IN PLACE
AND DELETE THE OTHER TWO.)
Level of experience: Beginner
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'beginner' level, so you can follow it
even if you have never developed a plugin or gadget before.
Level of experience: Intermediate
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'intermediate' level. If you have never
developed a plugin or gadget before, you may find this one a bit difficult.
Level of experience: Advanced
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'advanced' level. If you have never
developed a plugin or gadget before, we advise you to try a beginner tutorial first.
The source code of the plugin used in this tutorial is available in the Atlassian public source repository. You can check out the source code
here. (To the tutorial author: GIVE THE CORRECT LOCATION OF THE SOURCE CODE.)
On this page:
Overview
Required Knowledge
Step 1. Create the Plugin Project
Step 2. Add Plugin Metadata to the POM
Step 3. Create the Gadget Specification
Step 4. Register the Plugin Module in the Plugin Descriptor
Step 5. Add the Gadget to a Dashboard for Testing
Step 6. Make Resources Available to your Gadget
Step 7. Write Java Classes
Step 8. Make the Gadget Do Something Useful
Step 9. Build, Install and Run the Plugin
Step 10. Write Unit and Integration Tests
Step 11. Test your Updates on your Dashboard
Overview
This tutorial shows you how to write a gadget that XXXXXXXXX (To the tutorial author: TELL THEM WHAT THE GADGET WILL DO.)
Your gadget will be a 'plugin' gadget. That means that it will be embedded within an Atlassian plugin. The plugin will consist of the following
parts:
An Atlassian plugin descriptor, that is an XML file enabling the plugin in the Atlassian application. (To the tutorial author: GIVE THE
TARGET APPLICATION e.g. JIRA)
A gadget specification, that is an XML file containing the gadget's HTML, CSS and Javascript.
Java classes encapsulating the plugin logic.
Resources for display of the gadget UI. (To the tutorial author: REMOVE THIS LINE IF NOT APPLICABLE FOR THIS TUTORIAL)
All these components will be contained within a single JAR file. We will discuss each component in the examples below.
If you are interested, you can compare standalone gadgets and gadgets embedded in plugins.
Required Knowledge
(To the tutorial author: EXPLAIN WHAT THE GADGET AUTHOR NEEDS TO KNOW BEFORE THEY CAN START THIS TUTORIAL.
BELOW ARE SOME EXAMPLE WORDS. PLEASE ADAPT THEM TO FIT YOUR TUTORIAL.)
To complete this tutorial, you must already understand the basics of Java development: classes, interfaces, methods, how to use the
compiler, and so on. You should also understand:
How to create an Atlassian plugin project using the Atlassian Plugin SDK.
How to open the plugin project in your IDE.
How to compile your project and create a JAR file using Maven.
Step 1. Create the Plugin Project
First you need to set up your development environment and create your plugin project and source directories. Follow the instructions in our
guides:
Set up your development environment
Create and install your plugin from a template
When you create the plugin using the above SDK, you will be prompted for some information to identify your plugin. Enter the following
information:
group-id: com.example.plugins.tutorial
artifact-id: XXXXXXXXXXXX (To the tutorial author: GIVE THE ARTIFACT ID HERE)
version: 1.0
package: com.example.plugins.tutorial
Step 2. Add Plugin Metadata to the POM
Now you need to edit your POM (Project Object Model definition file) to add some metadata about your plugin and your company or
organisation.
1. Edit the pom.xml file in the root folder of your plugin.
2. Add your company or organisation name and your website to the <organization> element:
<organization>
<name>Example Company</name>
<url>http://www.example.com/</url>
</organization>
3. Update the <description> element:
<description>This plugin XXXXXXXXXX</description>
(To the tutorial author: ENTER A SHORT DESCRIPTION ABOVE)
4. Save the file.
Step 3. Create the Gadget Specification
Here is a basic gadget specification using the Atlassian Gadgets JavaScript Framework:
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="__MSG_gadget.title__" directory_title="__MSG_gadget.title__"
description="__MSG_gadget.description__">
<Require feature="dynamic-height" />
<Optional feature="auth-refresh"/>
<Require feature="oauthpopup" />
<Require feature="setprefs" />
<Require feature="settitle" />
<Require feature="views" />
<Optional feature="atlassian.util" />
<Optional feature="gadget-directory">
<Param name="categories">Other</Param>
</Optional>
#oauth
#supportedLocales("gadget.common,your.gadget.resource.prefix")
</ModulePrefs>
<Content type="html">
<![CDATA[
/* The #-directive below will include all required JavaScript and CSS resources needed to use
the Atlassian Gadgets JavaScript Framework. */
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
#includeResources()
<script type="text/javascript">
(function () {
/* (2) Construct and initialise the gadget */
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__", /* (3) Used to make the application's base URL
available to the gadget */
view: {...view-options...} /* (4) Defines the view logic and initialises the view */
});
})();
</script>
]]>
</Content>
</Module>
Copy the XML code from the above gadget specification and use it to add your gadget specification at (To the tutorial author: TELL THEM
WHERE TO PUT THE GADGET SPEC.)
Step 4. Register the Plugin Module in the Plugin Descriptor
Now you will add the gadget plugin module to your plugin descriptor at src/main/resources/atlassian-plugin.xml. The plugin
descriptor is an XML file that identifies the plugin to XXXXXXXXXXXX (To the tutorial author: ADD THE APPLICATION NAME e.g. JIRA) and
defines the functionality that the plugin requires.
1. Add the <gadget> the plugin module to your plugin descriptor, atlassian-plugin.xml.
(To the tutorial author: ADD THE GADGET KEY, LOCATION ETC IN THE XML BELOW.)
<atlassian-plugin key="${project.groupId}.${project.artifactId}"
name="${project.artifactId}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}" />
</plugin-info>
<gadget key="XXXXXXXXXXXX" location="XXXXXXXXXX.xml"/>
</atlassian-plugin>
2. Follow these steps to build and install your plugin, so that you can test your code:
If you have not already started the application, start it now:
Open a command window and go to the plugin root folder (where the pom.xml is located).
Run atlas-run.
From this point onwards, you can use the command line interface (CLI) as follows:
Open another command window and go to the plugin root folder.
Run atlas-cli in the second command window to start the CLI.
When you see the message 'Waiting for commands', run pi to compile, package and install the updated
plugin.
Go back to the browser. The updated plugin has been installed into the application, and you can test your changes.
The full instructions are in the SDK guide.
Step 5. Add the Gadget to a Dashboard for Testing
Your gadget can already do something: It can say 'Hello world!'. Test it by adding it to JIRA. You will need a developer or test JIRA instance
where you have administrative permission to add gadgets to that instance:
1. Go to a JIRA dashboard that you have created (or create a new one) and click 'Add Gadget'.
2. The 'Add Gadget' screen appears, showing the list of gadgets in your directory.
Your gadget should already appear in the list, because it is added as part of the plugin.
3. Click the 'Add it Now' button under your gadget to add the gadget to your dashboard.
Step 6. Make Resources Available to your Gadget
Your gadget will need XXXXXXX (To the tutorial author: TELL THEM WHAT RESOURCES THEY NEED e.g. IMAGES, JavaScript files, CSS
files, etc. OR REMOVE THIS SECTION IF NOT REQUIRED.)
1. Add the following resource definitions to your plugin descriptor, atlassian-plugin.xml:
(To the tutorial author: ADD THE RESOURCES IN THE XML BELOW.)
<resource type="download" name="XXXXXXXXXXX" location="XXXXXXXXXXXX/XXX"/>
<resource type="download" name="XXXXXX" location="XXXXXXXXXXXX/XXXX"/>
Step 7. Write Java Classes
In this plugin, you want to (To the tutorial author: TELL THEM WHAT WE WANT OUR PLUGIN TO DO)
(To the tutorial author: GIVE CODE SAMPLES AND NARRATIVE HERE.)
Step 8. Make the Gadget Do Something Useful
Now you will write the JavaScript and HTML code to retrieve data from XXXXXXXXX (To the tutorial author: TELL THEM WHERE THE
DATA WILL COME FROM, e.g. JIRA or CONFLUENCE or SOMEWHERE ELSE.) and display the information in the gadget.
The <Content> element in your gadget specification contains the working parts of the gadget. The <Content> element consists of:
A CDATA declaration, to prevent the XML parser from attempting to parse the gadget content. Include '<![CDATA[' (without the
quotes) at the beginning and ']]>' (without the quotes) at the end of your <Content> element.
Optional static HTML. When a dashboard renders the gadget, it will render this HTML.
Optional JavaScript. You can declare JavaScript functions and call them in the usual way. Refer to the OpenSocial JavaScript API
for details of gadget-specific API functions that any OpenSocial gadget container should support.
Optional CSS style sheets.
Because your gadget is embedded in a plugin, you can use the Atlassian Gadgets JavaScript Framework in addition to the OpenSocial
JavaScript API.
In this tutorial you will need a JavaScription function that xxxxxxxxxx (To the tutorial author: LEAD THEM THROUGH THE CREATION OF
THE JAVASCRIPT, HTML and CSS THAT THEY NEED.)
Step 9. Build, Install and Run the Plugin
Follow these steps to build and install your plugin, so that you can test your code:
If you have not already started the application, start it now:
Open a command window and go to the plugin root folder (where the pom.xml is located).
Run atlas-run.
From this point onwards, you can use the command line interface (CLI) as follows:
Open another command window and go to the plugin root folder.
Run atlas-cli in the second command window to start the CLI.
When you see the message 'Waiting for commands', run pi to compile, package and install the updated plugin.
Go back to the browser. The updated plugin has been installed into the application, and you can test your changes.
The full instructions are in the SDK guide.
Step 10. Write Unit and Integration Tests
(To the tutorial author: GIVE CODE SAMPLES AND NARRATIVE FOR UNIT AND INTEGRATION TESTS HERE.)
Step 11. Test your Updates on your Dashboard
Refresh your JIRA dashboard. Your updated content should be visible. (To the tutorial author: TELL THEM WHAT THEY SHOULD SEE.
GIVE SCREENSHOTS.)
Congratulations, that's it
Your gadget is complete. Have a chocolate!
Next Steps
Now that you have created a working gadget, you may like to look at some more advanced topics:
Internationalising your Gadget
Template for Standalone Gadget Tutorial
Please ignore this page unless you want to write a gadget tutorial
This page is just a template for tutorial developers to use when writing a new tutorial. The real tutorials are listed here:
Tutorials on Writing a Gadget.
(To the tutorial author: This is a template. You can copy the content of this page and use it to create your own gadget tutorial. When you
have finished, delete all sections that start with 'To the tutorial author' from your copy of the page. Otherwise the page will self-destruct when
you finish reading it.)
(To the tutorial author: CHOOSE ONE OF THE 3 LEVELS BELOW (beginner, intermediate or advanced), LEAVE THAT ONE IN PLACE
AND DELETE THE OTHER TWO.)
Level of experience: Beginner
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'beginner' level, so you can follow it
even if you have never developed a gadget before.
Level of experience: Intermediate
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'intermediate' level. If you have never
developed a gadget before, you may find this one a bit difficult.
Level of experience: Advanced
Our tutorials are classified as 'beginner', 'intermediate' and 'advanced'. This one is at 'advanced' level. If you have never
developed a gadget before, we advise you to try a beginner tutorial first.
On this page:
Overview
Required Knowledge
Step 1. Create the Gadget Specification
Step 2. Update the Gadget Title and Other Descriptive Details
Step 3. Make the Gadget Available on a Server
Step 4. Add the Gadget to a Dashboard for Testing
Step 5. Make the Gadget Do Something Useful
Step 6. Update the Gadget on the Server
Step 7. Test your Updates on your Dashboard
Overview
This tutorial shows you how to write a gadget that (To the tutorial author: TELL THEM WHAT THE GADGET WILL DO)
Your gadget will be a 'standalone' gadget. That means that it will consist entirely of HTML, CSS and Javascript, all contained within the
gadget XML specification. There is no plugin involved. If you are interested, you can compare standalone gadgets and gadgets embedded in
plugins.
Required Knowledge
(To the tutorial author: EXPLAIN WHAT THE GADGET AUTHOR NEEDS TO KNOW BEFORE THEY CAN START THIS TUTORIAL.
BELOW ARE SOME EXAMPLE WORDS. PLEASE ADAPT THEM TO FIT YOUR TUTORIAL.)
To complete this tutorial, you must already understand the following:
The basics of developing an Atlassian gadget.
Step 1. Create the Gadget Specification
1.
1. Copy the following code to create the basic XML file that will become your gadget specification:
2. Paste the code into a text editor and save the file as (To the tutorial author: GIVE A MEANINGFUL FILE NAME)
Step 2. Update the Gadget Title and Other Descriptive Details
1. Update the values of the following attributes in the <ModulePrefs> element of your gadget specification:
title
Enter 'XXXXX'. (To the tutorial author: GIVE A MEANINGFUL GADGET NAME)
description
Enter 'XXXXX'. (To the tutorial author: GIVE A MEANINGFUL DESCRIPTION)
author
Enter your own name.
author_email
Enter your own email address or remove this attribute.
2. Update the value of the categories parameter of the gadget-directory feature to 'XXXXX'. This controls which category your
gadget appears in within the JIRA gadget directory. (To the tutorial author: GIVE A MEANINGFUL CATEGORY. Valid values are
"JIRA", "Confluence", "FishEye", "Crucible", "Crowd", "Clover", "Bamboo", "Admin", "Charts", "External Content", and "Other".)
Step 3. Make the Gadget Available on a Server
Because you are developing a standalone gadget, you can host your gadget specification on any server that will make it available to a
dashboard. For this tutorial, you can host your gadget in the Atlassian public SVN repository.
Check in your gadget specification in the tutorials project.
Step 4. Add the Gadget to a Dashboard for Testing
Your gadget can already do something: It can say 'Hello world!'. Test it by adding it to JIRA. You will need a developer or test JIRA instance
where you have administrative rights to add gadgets:
1. Go to a JIRA dashboard that you have created (or create a new one) and click 'Add Gadget'.
2. The 'Add Gadget' screen appears, showing the list of gadgets in your directory. Click 'Add Gadget to Directory'.
3.
4.
5.
6.
You will only see this button if you have administrator permissions for your dashboard.
The 'Add Gadget to Directory' screen appears. Paste the gadget URL into the text box.
Click 'Add Gadget'.
The gadget appears in your gadget directory. (It will be highlighted for a short time, so that you can see it easily.)
Click the 'Add it Now' button under your gadget to add the gadget to your dashboard.
Step 5. Make the Gadget Do Something Useful
Now you will write the JavaScript and HTML code to retrieve data from XXXXXXXXX (To the tutorial author: TELL THEM WHERE THE
DATA WILL COME FROM, e.g. JIRA or CONFLUENCE or SOMEWHERE ELSE.) and display the information in the gadget.
The <Content> element in your gadget specification contains the working parts of the gadget. The <Content> element consists of:
A CDATA declaration, to prevent the XML parser from attempting to parse the gadget content. Include '<![CDATA[' (without the
quotes) at the beginning and ']]>' (without the quotes) at the end of your <Content> element.
Optional static HTML. When a dashboard renders the gadget, it will render this HTML.
Optional JavaScript. You can declare JavaScript functions and call them in the usual way. Refer to the OpenSocial JavaScript API
for details of gadget-specific API functions that any OpenSocial gadget container should support.
Optional CSS style sheets.
In this tutorial you will need a JavaScription function that xxxxxxxxxx (To the tutorial author: LEAD THEM THROUGH THE CREATION OF
THE JAVASCRIPT, HTML and CSS THAT THEY NEED.)
Step 6. Update the Gadget on the Server
1. Check in your updated gadget specification if it's in SVN, or upload the updated file to the server if it's just a static file somewhere.
2. Restart JIRA. (This step is required due to a caching issue that affects most gadgets on most gadget containers. See the information
box below.)
The gadget caching issue
JIRA will cache the gadget specification, with the result that your updates will not appear in JIRA until the cache has timed
out or you restart JIRA. This caching problem affects other containers too, including iGoogle. There are workarounds, but
these are too complex for this tutorial. Here's a short summary of the workarounds, in case you find them useful:
In JIRA, you need to restart JIRA or run it in development mode.
In iGoogle, you can use the Google 'My Gadgets' gadget, which allows you to turn off caching for specific gadgets.
See our tips on using the iGoogle development environment.
Step 7. Test your Updates on your Dashboard
Test your updated gadget on the JIRA dashboard. (To the tutorial author: TELL THEM WHAT THEY SHOULD SEE. GIVE SCREENSHOTS.)
Congratulations, that's it
Your gadget is complete. Have a chocolate!
Next Steps
Now that you have created a working gadget, you may like to look at some more advanced topics:
Internationalising your Gadget
Packaging your Gadget as an Atlassian Plugin
Gadgets and JIRA Portlets
This page compares JIRA portlets with gadgets.
On this page:
What's Changed
JIRA Portlet-to-Gadget Bridge
Converting a JIRA Portlet to a Gadget
What's Changed
From a user's perspective...
In JIRA versions prior to 4.0, you could configure your dashboard by adding portlets. In JIRA 4.0 and later, portlets have been converted to
industry-standard gadgets.
From a developer's perspective...
In the portlets world, you do everything server-side (on the server where the data is held) and use your portlet class and your Velocity
templates to render the UI.
In the gadgets world, the UI is rendered entirely using HTML and JavaScript (on the dashboard server). To get dynamic data into the gadget,
you will make Ajax calls using makeRequest back to the originating server.
Why a special API for making requests? When we render gadgets, even if the gadget specification is coming from your server out there, it is
pulled into the dashboard server and parsed and rendered into HTML on the dashboard server. So your JavaScript can only talk to the server
where the dashboard is running. The makeRequest call will proxy back (in a process that is called 'phoning home') to the originating server
to request data, using one of the following:
The REST APIs that the application already supports.
A custom servlet that you build in a plugin for that product.
A custom REST plugin module. This is the recommended option.
Here is a summary of the difference between gadgets and portlets, from the perspective of a JIRA portlet developer:
With gadgets you will not have to write any Java, unless you need to create a new REST API.
All you need to do is write the gadget specification file and deploy it into JIRA. That's it.
If you need to access internal data for reporting, have customised APIs, etc, you will be able to access those as well.
The container handles a lot of stuff for you, such as:
HTTP caching.
Rendering the content to the browser.
You will write JavaScript to make a request to the remote APIs, to grab the data and populate the content. This replaces the Java
code you need to write for a portlet, that populates a Velocity template, context etc.
JIRA Portlet-to-Gadget Bridge
We have built a bridge so that you do not have to convert all the JIRA portlets to gadgets right away. Instead, you can use the bridge to
display your existing portlet's output on your JIRA gadgets dashboard.
The bridge will not work for all the portlets. Some portlets contain advanced Ajax functionality that will not be pulled into the gadget properly.
But you should be able to make backwards-compatible changes to most portlets that will allow them to work in the bridge as well as in older
versions of JIRA.
Note: The bridge is applicable to existing portlets only and is an interim solution. Such legacy portlets can run only on:
JIRA dashboards, not iGoogle or Confluence or other OpenSocial containers.
The gadget's local instance of JIRA, i.e. the portlet cannot pull information from another JIRA installation, as a gadget can
Test before deploying to JIRA 4 in production
Be sure to test your portlets in a JIRA 4 dashboard before deploying to a production instance of JIRA 4.
Converting a JIRA Portlet to a Gadget
We will have more information from this page after the Atlassian Summit. Tim is doing a presentation that we can adapt for this page.
There are three options for converting a portlet to a gadget:
1. Use the legacy bridge described above.
Pros: Easy (should just work automatically); can deploy one plugin to older JIRA versions as well as JIRA 4.
Cons: Cannot take advantage of gadget features; may not be the fastest; legacy portlet API is deprecated and may be
removed in the future; no way to make this kind of gadget work cross-application on the server-side. (The portlets from JIRA
can still be displayed in other gadget containers, so this is not a big con for that many people.)
2. Convert the portlet to a servlet or webwork plugin module that renders the content pretty much exactly the same way the portlet did.
Then write a gadget that uses gadgets.io.makeRequest to get those contents, and replaces the body of the gadget with the
retrieved contents.
Pros: Easier than rewriting entirely as a gadget; can make use of gadget APIs; may be more familiar technology for people
used to writing portlets (server-side Java servlets and Velocity templates, versus JavaScript/AJAX).
Cons: Not ideal from a performance standpoint; does not take full advantage of dynamic JavaScript UI capabilities; using
JavaScript and CSS might be awkward; difficult to make backwards-compatible with older JIRA versions.
3. Rewrite the portlet as a proper gadget, using a REST API to retrieve the data you need from JIRA using
gadgets.io.makeRequest, and DOM manipulation in JavaScript to handle the UI.
Pros: Allows you to take full advantage of modern AJAX UI techniques; may have performance benefits; best way to take
advantage of caching.
Cons: May require a substantial rewrite; may require learning a lot of new technology; difficult or impossible to make
backwards-compatible with older JIRA versions.
RELATED TOPICS
Using Atlassian REST APIs in your Gadget
Writing an Atlassian Gadget
Gadget Developer Documentation
Writing a Plugin Upgrade Task for JIRA 4.0 (in the JIRA documentation)
Gadgets and Dashboards Version Matrix
This page describes the level of support that each Atlassian application provides for the Atlassian Gadgets and Dashboards framework.
Version Matrix
The matrix below shows the Atlassian applications which provide at least some support for Atlassian gadgets, and the gadget capabilities
supported.
(If the application version number is in brackets, this indicates a future release of the application that is expected to support the capabilities
described.)
Application
Atlassian Gadget Version
Capabilities
Bamboo 2.3.x
Atlassian Gadgets 1.0
Gadget Publication
Bamboo 2.4.x
Atlassian Gadgets 1.0
Gadget Publication
Bamboo 2.5.x
Atlassian Gadgets 2.0
Gadget Publication
Bamboo 2.6.x
Atlassian Gadgets 2.0.3
Gadget Publication
Confluence 3.1.x
Atlassian Gadgets 2.0
Gadget Publication
Gadget Display
Confluence 3.2.x
Atlassian Gadgets 2.0.2
Gadget Publication
Gadget Display
Crucible 2.0.x
Atlassian Gadgets 1.0
Gadget Publication
Crucible 2.1.x
Atlassian Gadgets 1.0
Gadget Publication
Crucible 2.3.x
Atlassian Gadgets 2.0.2
Gadget Publication
Crucible 2.4.x
Atlassian Gadgets 2.0.4
Gadget Publication
FishEye 2.0.x
Atlassian Gadgets 1.0
Gadget Publication
FishEye 2.1.x
Atlassian Gadgets 1.0
Gadget Publication
FishEye 2.3.x
Atlassian Gadgets 2.0.2
Gadget Publication
FishEye 2.4.x
Atlassian Gadgets 2.0.4
Gadget Publication
JIRA 4.0.0
JIRA 4.0.1
Atlassian Gadgets 1.0
Gadget Publication
Gadget Display
Configurable Dashboards
JIRA 4.0.2
Atlassian Gadgets 1.1.2
Gadget Publication
Gadget Display
Configurable Dashboards
JIRA 4.1.x
Atlassian Gadgets 1.1.5
Gadget Publication
Gadget Display
Configurable Dashboards
JIRA 4.2.x
Atlassian Gadgets 1.1.5
Gadget Publication
Gadget Display
Configurable Dashboards
JIRA 4.3.x
Atlassian Gadgets 2.0
Gadget Publication
Gadget Display
Configurable Dashboards
Gadget Subscription
Explanation of the Capabilities
Capability
Description
Gadget
Publication
The application provides gadgets for use by itself or other applications. In technical terms, the application is able to serve
gadget specification files for consumption by Atlassian or non-Atlassian gadget containers. Typically, the gadget
specification files are bundled into plugins. The plugins may be bundled with the application or installed later.
Gadget
Display
The host application supports some mechanism for embedding and displaying individual gadgets in a page or dashboard.
In technical terms, the gadget contents is rendered via the Atlassian Gadgets Renderer and Shindig.
Configurable
Dashboards
The application offers one or more read/write dashboards supporting multiple gadgets and a customised layout.
Gadget
Subscription
The application allows the administrator to "subscribe" to another application's gadgets. This means that all the gadgets
published by the second application will be available to the first application. There is no need to add each gadget via its
URL.
RELATED TOPICS
Gadget Developer Documentation
Information sourced from Gadgets documentation
Development Resources
Reference Documents
Development FAQ
Reference Documents
Below are links to some useful articles and blog posts on gadget development, OpenSocial and related topics.
On this page:
Google Gadgets
OpenSocial
OAuth
Shindig
Google Gadgets
Google Code — Home of the official gadget specifications and documentation.
Gadgets Developer Guide — Reference for gadget authors.
Google Gadgets Tutorial — From an independent (non-Google) developer.
OpenSocial
OpenSocial.org — Official home of the OpenSocial Foundation.
OpenSocial Specs — Official technical specifications.
OpenSocial - Google Code — Home of Google's documentation on building OpenSocial applications and containers.
Building a Container
OpenSocial API Documentation
OpenSocial Community Wiki — Where new specification proposals are developed
OpenSocial Directory
OpenSocial Java Client Library — A Java library for using the OpenSocial v0.8 REST API (not needed for most simple gadgets, only
for server-side components).
OAuth
OAuth
Google OAuth & Federated Login Research
Google Online Security Blog
Validating Signed Requests
OAuth for gadgets
OAuth Core 1.0 "Editor's Cut"
OAuth Service Providers
OAuth Session Fixation Attack (Shindig wiki)
Shindig
Shindig
Shindig Community Wiki
Shindig Website Staging Wiki
Shindig Architecture Articles
Shindig Architectural Overview Nov 2008
Shindig Architecture: Java Gadget Classes
Shindig Java internals diagram
(Answers to) Questions about implementing Shindig
Shindig Java Style Guide
Locking Down Shindig
Shindig Git Clone
Google Gadgets & Shindig RPC Enlightment
Development FAQ
Here is a list of all entries in the development FAQ, plus the first few lines of content. Click a link to see the full text for each entry.
Finding Known Issues and Workarounds — Please refer to the open and recently-resolved issues for the Atlassian Gadgets project.
This project includes development of both gadgets and dashboards.
Developing Standalone or Plugin Gadgets
Hints for Developing in iGoogle Sandbox
Finding Known Issues and Workarounds
Please refer to the open and recently-resolved issues for the Atlassian Gadgets project. This project includes development of both gadgets
and dashboards.
Below is a list of the open issues.
Before reporting a bug or requesting a new feature, please take a look to see if it has already been reported.
If you find a likely-looking issue, click the link to find more information and possible workarounds.
JIRA Issues (25 issues)
Type Key
Summary
AG-1398 Setting refresh=true causes gadget to refresh as fast as possible
Reporter
Matt Ryall
Scott
Status
Open
AG-1396 Editing a gadget while in canvas mode causes the gadget iframe to be clipped
Harwood
AG-1395 GadgetSpecFactory does not timeout if an external gadget provider does not respond.
Brian Nguyen
AG-1392 Dup'd I18N keys in AG
Jonathan
Nolen
AG-1390 close boxes are omitted by overridden version of AJS.messages
Eli Bishop
AG-1382 WebSudo prevents gadgets from accessing protected resources
John Kodumal
AG-1381 jsonp requests will not work within gadgets
Zachary Davis
AG-1373 Gadget directory categories count is not updated after a gadget is removed from the directory
Dariusz
Kordonski
Open
AG-1372 Improve permission error when logged out
Andreas
Knecht
Open
AG-1370 Gadgets should follow Style Guide where appropriate
Zachary Davis
AG-1369 Too aggressive in caching anonymous requests
Brian
McKenna
AG-1368 IE9: Gadget menu is broken
Zachary Davis
AG-1367 IE9: Resizing of gadget is broken
Zachary Davis
AG-1364 Need ability to clear the cache within the DefaultMessageBundleFactory
Ian Grunert
AG-1362 GadgetViewComponent ignores ViewType
John Kodumal
AG-1361 Removing dropdowns and re-appending them to the top window loses any registered events
Zachary Davis
AG-1360 Failed configuration validation submit does not properly fill in error messages into form
Michael Ruflin
AG-1357 Switching to canvas mode re-encodes spaces
Zachary Davis
AG-1356 Gadget in canvas mode does not always resize properly
Zachary Davis
AG-1354
AG Leaves the GadgetInstallationThread running for the JIRA run even though it is not used
99.999999% of the time.
Brenden Bain
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
Open
AG-1343 No padding in Finished button in Gadget Directory in Safari 5
Andreas
Knecht
Open
AG-1342 Buttons in gadget config have scrolling container
Andreas
Knecht
Open
AG-1340 OAuth Login & Approve button is squashed in Chrome
Andreas
Knecht
Open
AG-1339 Padding at bottom of gadget configuration screen is different if login and approve button exists.
Andreas
Knecht
Open
AG-1338 "Add" buttons are too wide in German in the Gadget Directory
Andreas
Knecht
Open
Developing Standalone or Plugin Gadgets
How feasible is it to create an Atlassian gadget that consists purely of HTML, CSS and Javascript? Assuming that the Confluence or JIRA (or
whatever) REST API could do everything that the gadget needs, can you bypass the plugin side of things altogether?
You can choose to write a standalone gadget or a gadget embedded in a plugin.
A standalone gadget consists entirely of HTML, CSS and Javascript, all contained within the gadget XML file. To retrieve data from
an application, you can use a REST API, for example.
Alternatively you can write a gadget and a plugin, and embed the gadget into the plugin XML using the gadget plugin module. The
plugin needs to be installed into the Atlassian application, such as JIRA or Confluence.
Limitations if you do not embed your gadget in a plugin:
You will not be able to use #-directives. This means that, if your gadget is requesting data from an Atlassian application, the gadget
can only access a single, specific instance of that application because you will need to hard-code the base URL.
It is significantly more difficult to use the Atlassian Gadget JavaScript Framework, because you will need to code everything that is
normally automatically generated by the #supportedLocales and #includeResources directives.
That said, there are two main reasons why you may be interested in writing standalone gadgets:
It is a much simpler way to write very basic gadgets. This provides an easier way to learn how to write gadgets.
A non-plugin gadget may be sufficient if your gadget is for your own company's internal use with a single Atlassian application/site.
You may want to write gadgets that request data from some non-Atlassian system or web service, in order to integrate that data into
an Atlassian application such as JIRA or Confluence.
RELATED TOPICS
Packaging your Gadget as an Atlassian Plugin
Hints for Developing in iGoogle Sandbox
If you decide to play around with developing your own Google Gadgets, you may find these notes useful. They are gathered from the
experiences of other developers using iGoogle sandbox for the first time.
Hints:
1. There are two Google gadget developer guides, one for the earlier 'legacy' version of the Google gadget API and one for the new
version which supports OpenSocial. Make sure you use the new one.
2. Here is the guide for the iGoogle sandbox, a development environment provided by Google where you can develop gadgets for
iGoogle.
3. To sign up for the sandbox, you need a Gmail account. Then go to this URL: http://www.google.com/ig/sandbox. Sign up using your
Gmail email address. But there is a catch: If you go to the above URL again, you will be signed out of the sandbox! Then you will
need to sign up again at the same URL. Just give the same information again, and you will get your sandbox access back with all
your gadgets intact.
4. You will know you are in the sandbox when the following words appear near the top left of your iGoogle page: 'Welcome to the
iGoogle Developer sandbox'.
5. Your iGoogle sandbox appears as a new tab on your iGoogle page. After signing up, just examine your iGoogle page to see what
has magically appeared on it.
6. The editor in which you create the gadgets is actually a gadget itself. So to use it, you need to add it to your iGoogle page (i.e. the
sandbox) in the same way as you would add any other gadget. For some reason, it is not auto-added to your sandbox even though a
number of other gadgets do automatically appear there. Your first experience of the editor is just as a text box in the middle of the
developer's guide, here. But you don't have to keep going back to that page to edit your gadgets.
7. In your iGoogle sandbox, you will have a list of gadgets displayed within another gadget called 'My Gadgets'. This is where you add
gadgets to your sandbox.
8. For the gadgets you are busy developing, it is a good idea to uncheck the 'Cached' checkbox in the 'My Gadgets' list, so that you
can see the results of your changes immediately.
9. When you create a new gadget and save it in the editor, copy the new URL. It is at the top right of the editor box. Then add the
gadget to the 'My Gadgets' list immediately. Otherwise you may have difficulty finding your gadget again.
10. Save your gadget code somewhere else as well as in the gadget editor, e.g. on your own machine using a text editor like Notebook.
The Google gadget editor sometimes does some odd things, especially when you are copying code from one gadget to another.
11. If your gadget does not display the output you are expecting, look for the basic misplaced bracket or whatever, rather than assuming
it is some weird gadgety thing that is causing the problem.
RELATED TOPICS
Writing an Atlassian Gadget
Creating your Gadget XML Specification
Using Substitution Variables and Directives in your Gadget
Allowing Configuration Options in your Gadget
Including Features into your Gadget
Packaging your Gadget as an Atlassian Plugin
Internationalising your Gadget
Using Web Resources in your Gadget
Using Atlassian REST APIs in your Gadget
Providing User Authentication for Gadgets
Using the Atlassian Gadgets JavaScript Framework
Managing Caching for your Gadget
Gadgets and Dashboards Glossary
Here is a list of all entries in the glossary, plus the first few lines of content. Click a link to see the full text for each entry.
Application Programming Interface or API (Glossary Entry) — An application programming interface or API is an interface defined
and implemented by the Atlassian Gadgets framework that is used by host applications to invoke operations provided by Atlassian
Gadgets. For example, there are APIs for rendering gadgets and dashboards, loading and saving dashboards, and fetching and
parsing gadget XML specifications.
Atlassian Gadgets (Glossary Entry) — The term 'Atlassian gadgets' has two meanings. Firstly, Atlassian gadgets are similar to
Google gadgets and provide additional options allowing interaction with Atlassian applications such as JIRA and Confluence.
Secondly, the term 'Atlassian Gadgets' (usually with initial capital letters) means the development framework that allows you to
develop your own Atlassian gadget.
Atlassian Gadgets Support Level or AGSL (Glossary Entry) — An Atlassian Gadgets Support Level (AGSL) is a number (0, 1, 2, etc)
indicating the level of support an application provides for Atlassian gadgets. An AGSL is one of several stages of integration between
Atlassian gadgets and a host application. See the application support levels.
Container (Glossary Entry) — A container is an application or web page that embeds and displays gadgets, either on a dashboard or
individually on a page. The application may offer a configurable dashboard where the user can add gadgets. Or the application may
offer another means of displaying a gadget, such as a macro which embeds the gadget into a wiki page.
Dashboard (Glossary Entry) — A dashboard is typically the landing page of an application such as JIRA or Confluence, providing an
entry point into the different levels of functionality within the application. For applications that support Atlassian gadgets, the
dashboard is a container where users can add gadgets and personalise their dashboard display.
Directive (Glossary Entry) — The Atlassian Gadgets framework allows you to specify #-directives in your gadget specification XML
file that will be replaced by generated content at run time. These #-directives are provided by the Atlassian Gadget Publisher plugin.
They work for any gadget that is provided as a plugin in an Atlassian application. The #-directives do not work for gadgets that are
served from an external web server.
Directory (Glossary Entry) — The gadgets directory displays a list of available gadgets, allowing users to select a gadget for
installation onto their dashboard. In the future we will extend the functionality offered by the directory, so that it also allows users to
comment on and rate gadgets. Administrators can add external gadgets to the directory, making the gadgets available for users to
add to their dashboards.
Gadget (Glossary Entry) — A gadget is a small object (i.e. a piece of functionality) offering dynamic content that can be displayed in
a container. Google gadgets are one type of gadget. Atlassian gadgets are similar, providing additional options allowing interaction
with Atlassian applications such as JIRA and Confluence.
Gadget Publisher Plugin (Glossary Entry) — The Gadget Publisher is a plugin to be installed into an Atlassian application, giving the
application the ability to produce gadgets for display in other applications.
Gadget Renderer Plugin (Glossary Entry) — This plugin has been renamed to the OpenSocial plugin in Atlassian Gadgets 2.0 and
later.
Host Application (Glossary Entry) — The host application (or host) is an application that integrates with Atlassian gadgets by using
the application programming interface (API) and provides implementations of the service provider interface (SPI).
OAuth (Glossary Entry) — OAuth is an open protocol allowing web applications to authorize other applications to access their data
and services on the behalf of their users. OAuth is the recommended mechanism for an Atlassian gadget that needs to authenticate
a user before displaying information on a web page.
OpenSocial (Glossary Entry) — The main aim of OpenSocial is to define a common API for social applications across multiple
websites. Using standard JavaScript and HTML, developers can create applications that access a social network's friends and
feeds. Applications that use the OpenSocial APIs can be embedded within a social network itself or access a site's social data from
anywhere on the web. OpenSocial applications are based on Google gadgets technology, and gadgets have been standardised as
part of the OpenSocial effort. The Atlassian Gadgets framework is based on version 0.8 of the gadget specification from OpenSocial,
but does not currently support other parts of OpenSocial, such as the social data or web service APIs.
OpenSocial Plugin (Glossary Entry) — The OpenSocial plugin is installed into Atlassian applications, giving the application the ability
to render (display) the contents of gadgets. Host applications rarely interact with this plugin directly. It is mostly a wrapper around
Shindig that integrates Shindig into an Atlassian plugin framework container. This plugin also includes the part of Shindig that
handles the OpenSocial data APIs. Note that these APIs are not yet used by Atlassian applications. This plugin was previously
called the Gadget Renderer plugin.
Plugin Exchange Manager (Glossary Entry) — Plugin Exchange Manager is an earlier name for the Universal Plugin Manager.
Plugin Framework 2 (Glossary Entry) — The Atlassian Plugin Framework 2 is the latest development framework allowing developers
to build plugins for Atlassian applications. A plugin is a bundle of code, resources and configuration files that can be dropped into an
Atlassian product to add new functionality or change the behaviour of existing features. Refer to the Atlassian Plugin Framework
documentation.
Reference Implementation (Glossary Entry) — The reference implementation (or refimpl) is an application with no features and no
functionality. Instead, it represents the lowest common denominator of all the Atlassian applications. In this way the reference
implementation provides a way of codifying the shared framework in all the applications. The reference implementation of Atlassian
Gadgets allows gadget authors to test gadgets in a lightweight dashboard container without having to install and launch a full product
such as JIRA.
REST Plugin Manager (Glossary Entry) — RPM is an earlier name for the Plugin Exchange Manager.
Service Provider Interface or SPI (Glossary Entry) — A service provider interface or SPI is an interface defined by the Atlassian
Gadgets framework that is implemented by host applications. An application or container will implement a number of SPIs in order to
support Atlassian Gadgets at the various support levels.
Shared Access Layer or SAL (Glossary Entry) — The Atlassian Shared Access Layer (SAL) provides a consistent, cohesive API to
common plugin tasks, regardless of the Atlassian application into which your plugin is deployed. Refer to the SAL documentation.
Shindig (Glossary Entry) — Apache Shindig is the reference implementation of the OpenSocial API specifications that provides the
code to render gadgets, proxy requests, and handle REST and RPC requests.
Trusted Application Authentication (Glossary Entry) — Trusted application authentication (or 'trusted apps') is an
Atlassian-developed mechanism allowing two applications to exchange information on behalf of a logged-in user. Atlassian Gadgets
can use trusted application authentication to allow transparent authorization of gadgets running in an Atlassian gadget container
application to access data and services from other Atlassian applications that have been configured to trust it. For example, an
administrator can configure JIRA and Confluence to communicate in a trusted way, so that Confluence can request information from
JIRA on behalf of the currently logged-in user. JIRA will not ask the user to log in again or to supply a password.
Universal Plugin Manager (Glossary Entry) — The Universal Plugin Manager (UPM) provides an interface for plugin management
within an application. The UPM is itself a plugin to be installed in Atlassian applications. The UPM also interfaces with the Atlassian
Plugin Exchange.
RELATED TOPICS
Gadget Developer Documentation
Application Programming Interface or API (Glossary Entry)
An application programming interface or API is an interface defined and implemented by the Atlassian Gadgets framework that is used by
host applications to invoke operations provided by Atlassian Gadgets. For example, there are APIs for rendering gadgets and dashboards,
loading and saving dashboards, and fetching and parsing gadget XML specifications.
Atlassian Gadgets (Glossary Entry)
The term 'Atlassian gadgets' has two meanings. Firstly, Atlassian gadgets are similar to Google gadgets and provide additional options
allowing interaction with Atlassian applications such as JIRA and Confluence. Secondly, the term 'Atlassian Gadgets' (usually with initial
capital letters) means the development framework that allows you to develop your own Atlassian gadget.
Atlassian Gadgets Support Level or AGSL (Glossary Entry)
An Atlassian Gadgets Support Level (AGSL) is a number (0, 1, 2, etc) indicating the level of support an application provides for Atlassian
gadgets. An AGSL is one of several stages of integration between Atlassian gadgets and a host application. See the application support
levels.
RELATED TOPICS
Gadgets and Dashboards Version Matrix
Container (Glossary Entry)
A container is an application or web page that embeds and displays gadgets, either on a dashboard or individually on a page. The application
may offer a configurable dashboard where the user can add gadgets. Or the application may offer another means of displaying a gadget,
such as a macro which embeds the gadget into a wiki page.
RELATED TOPICS
Gadget Containers
Dashboard (Glossary Entry)
A dashboard is typically the landing page of an application such as JIRA or Confluence, providing an entry point into the different levels of
functionality within the application. For applications that support Atlassian gadgets, the dashboard is a container where users can add
gadgets and personalise their dashboard display.
RELATED TOPICS
Gadgets and Dashboards Administration Guide
Gadgets and Dashboards User Guide
Directive (Glossary Entry)
The Atlassian Gadgets framework allows you to specify #-directives in your gadget specification XML file that will be replaced by generated
content at run time. These #-directives are provided by the Atlassian Gadget Publisher plugin. They work for any gadget that is provided as a
plugin in an Atlassian application. The #-directives do not work for gadgets that are served from an external web server.
#-directives are sometimes also called 'macros' or 'pseudo-macros'.
Directory (Glossary Entry)
The gadgets directory displays a list of available gadgets, allowing users to select a gadget for installation onto their dashboard. In the future
we will extend the functionality offered by the directory, so that it also allows users to comment on and rate gadgets. Administrators can add
external gadgets to the directory, making the gadgets available for users to add to their dashboards.
Gadget (Glossary Entry)
A gadget is a small object (i.e. a piece of functionality) offering dynamic content that can be displayed in a container. Google gadgets are one
type of gadget. Atlassian gadgets are similar, providing additional options allowing interaction with Atlassian applications such as JIRA and
Confluence.
Gadget Publisher Plugin (Glossary Entry)
The Gadget Publisher is a plugin to be installed into an Atlassian application, giving the application the ability to produce gadgets for display
in other applications.
Gadget Renderer Plugin (Glossary Entry)
This plugin has been renamed to the OpenSocial plugin in Atlassian Gadgets 2.0 and later.
Host Application (Glossary Entry)
The host application (or host) is an application that integrates with Atlassian gadgets by using the application programming interface (API)
and provides implementations of the service provider interface (SPI).
OAuth (Glossary Entry)
OAuth is an open protocol allowing web applications to authorize other applications to access their data and services on the behalf of their
users. OAuth is the recommended mechanism for an Atlassian gadget that needs to authenticate a user before displaying information on a
web page.
RELATED TOPICS
Providing User Authentication for Gadgets
OpenSocial (Glossary Entry)
The main aim of OpenSocial is to define a common API for social applications across multiple websites. Using standard JavaScript and
HTML, developers can create applications that access a social network's friends and feeds. Applications that use the OpenSocial APIs can
be embedded within a social network itself or access a site's social data from anywhere on the web. OpenSocial applications are based on
Google gadgets technology, and gadgets have been standardised as part of the OpenSocial effort. The Atlassian Gadgets framework is
based on version 0.8 of the gadget specification from OpenSocial, but does not currently support other parts of OpenSocial, such as the
social data or web service APIs.
OpenSocial Plugin (Glossary Entry)
The OpenSocial plugin is installed into Atlassian applications, giving the application the ability to render (display) the contents of gadgets.
Host applications rarely interact with this plugin directly. It is mostly a wrapper around Shindig that integrates Shindig into an Atlassian plugin
framework container. This plugin also includes the part of Shindig that handles the OpenSocial data APIs. Note that these APIs are not yet
used by Atlassian applications. This plugin was previously called the Gadget Renderer plugin.
Plugin Exchange Manager (Glossary Entry)
Plugin Exchange Manager is an earlier name for the Universal Plugin Manager.
Plugin Framework 2 (Glossary Entry)
The Atlassian Plugin Framework 2 is the latest development framework allowing developers to build plugins for Atlassian applications. A
plugin is a bundle of code, resources and configuration files that can be dropped into an Atlassian product to add new functionality or change
the behaviour of existing features. Refer to the Atlassian Plugin Framework documentation.
Reference Implementation (Glossary Entry)
The reference implementation (or refimpl) is an application with no features and no functionality. Instead, it represents the lowest common
denominator of all the Atlassian applications. In this way the reference implementation provides a way of codifying the shared framework in
all the applications. The reference implementation of Atlassian Gadgets allows gadget authors to test gadgets in a lightweight dashboard
container without having to install and launch a full product such as JIRA.
RELATED TOPICS
[Running your Gadget in the Atlassian Reference Implementation]
REST Plugin Manager (Glossary Entry)
RPM is an earlier name for the Plugin Exchange Manager.
Service Provider Interface or SPI (Glossary Entry)
A service provider interface or SPI is an interface defined by the Atlassian Gadgets framework that is implemented by host applications. An
application or container will implement a number of SPIs in order to support Atlassian Gadgets at the various support levels.
Shared Access Layer or SAL (Glossary Entry)
The Atlassian Shared Access Layer (SAL) provides a consistent, cohesive API to common plugin tasks, regardless of the Atlassian
application into which your plugin is deployed. Refer to the SAL documentation.
Shindig (Glossary Entry)
Apache Shindig is the reference implementation of the OpenSocial API specifications that provides the code to render gadgets, proxy
requests, and handle REST and RPC requests.
Trusted Application Authentication (Glossary Entry)
Trusted application authentication (or 'trusted apps') is an Atlassian-developed mechanism allowing two applications to exchange information
on behalf of a logged-in user. Atlassian Gadgets can use trusted application authentication to allow transparent authorization of gadgets
running in an Atlassian gadget container application to access data and services from other Atlassian applications that have been configured
to trust it. For example, an administrator can configure JIRA and Confluence to communicate in a trusted way, so that Confluence can
request information from JIRA on behalf of the currently logged-in user. JIRA will not ask the user to log in again or to supply a password.
Universal Plugin Manager (Glossary Entry)
The Universal Plugin Manager (UPM) provides an interface for plugin management within an application. The UPM is itself a plugin to be
installed in Atlassian applications. The UPM also interfaces with the Atlassian Plugin Exchange.
Download PDF