Adding data providers to your plugin
Examples of data that you may want to expose to the client are:
- plugin configuration options, for example, configuration that can be changed by an application administrator
- information about the currently logged-in user, such as user details, recently viewed issue keys, or recently viewed pages
- per-user configuration, such as whether the current user has seen onboarding information
A plugin is a good candidate for converting to a data provider, if there is any code in the plugin that either:
- executes an AJAX request on page load, or
- serializes configuration data into HTML during page rendering (e.g. using a
Note that currently, data providers can only retrieve the global context, such as the logged-in user or per-instance configuration. Data providers do not have access to any context relating to the page being rendered. For example, a data provider can't find out if the current page is a "view issue page" or what the key of the issue being rendered is.
A demonstration plugin using data providers is available at https://bitbucket.org/atlassian/page-data-demo. Code samples on this page are taken from that repository.
Using data providers
There are two ways to use data providers:
- in a
- directly during page rendering.
Defining a data provider in a web resource
As a plugin author (for example, if you are enhancing a page by adding yourself to a web-resource context), you should declare a data provider in a
Data providers have two required attributes:
- key - The key that client-side code will use to retrieve your JSON data. See Consuming a data provider below.
- class - The class implementation that provides data. This class must implement the
WebResourceDataProviderinterface, detailed below.
com.atlassian.webresource.api.data.WebResourceDataProvider) is the interface for all data providers. It contains a single method:
See About Jsonable's below for information on what this
get() method should be returning.
Injecting data during page rendering
If you are rendering a page yourself, you can inject JSON data directly into the page by using the
com.atlassian.webresource.api.assembler.PageBuilderService is an injectable service, used when building HTML pages.
com.atlassian.json.marshal.Jsonable) is an interface that streams JSON data to a
To implement a simple
DataProvider, you can return a simple Jsonable interface such as
JsonableString wraps a string in the Jsonable interface. Similar wrappers exist for Booleans (
JsonableBoolean) and Number (
Providing large data
The Jsonable interface is designed to be streamy. For larger objects, using the
Jsonable interface correctly means that the JSON representation of your data will be written directly to the HTTP output stream. This avoids serialization to a potentially large JSON string in-memory.
You can provide your own lightweight
Jsonable in your
WebResourceDataProvider. The following code converts a GSON object to the
Consuming a data provider
<data> element means that the object it returns will be serialized as JSON and sent to the HTML page being rendered.
To access this data in the browser, call:
complete-data-key is of the form
artifactIdare the relevant values for your plugin
web-resource-keyis the key of the
<web-resource>in which your
<data>element is defined
data-keyis the key on your
An example from the sample plugin is:
There are two important things to note about using data on the client:
WRM.data.claimcan *only be called once for a single data key*. The clientside web-resource manager (WRM) releases the data object for garbage collection after the first time it's claimed. If you want to access the data multiple times from your JS code, it's up to you to store it in your own variable. This behaviour was chosen to support use cases involving large data blobs. For example, a data provider may return a collection of JIRA issues to render client-side. This web-resource manager should not hold onto this collection internally after it's first claimed.
- Within a single
<data>elements will always be rendered onto the page before
WRM.data.claim" on a