So far as have seen that we can add web items to new or existion web sections, and use conditions to determine whether they should be displayed for the current user, or issue, page etc.

However, if you want to dynamically generate web items according to the current circumstances, you need a web item provider. Official documentation is lacking, vote for PLUGFRAG-17.

Examples of a web item provider might be:

These examples are for JIRA, but something similar should work for Bitbucket. Confluence does not support these at the time of writing.

Usage

First of all, let’s look at a simple example. For the web item provider, you must either provider a class that implements com.atlassian.plugin.web.api.provider.WebItemProvider, or, more simply, a script that returns a collection of com.atlassian.plugin.web.api.WebItem. Using a com.atlassian.plugin.web.api.model.WebFragmentBuilder is the easiest way to create a collection of WebItem.

Set up the fragment like in the following screen capture:

item provider simple

The provider class/script can either under a script root, or inline. Here is a simple example:

import com.atlassian.plugin.web.api.model.WebFragmentBuilder

["Foo", "Bar", "Quz"].collect {
    new WebFragmentBuilder(50). (1)
        id("sample-web-item-${it.toLowerCase()}"). (2)
        label("$it Sample Web Item").
        title("$it Sample Web Item Title").
        styleClass("").
        addParam("data-my-key", "data-value"). (3)
        addParam("iconUrl", "/jira/images/icons/priorities/highest.svg"). // not all places will show icons
        webItem(""). (4)
        url("/").
        build()
}
1 The 50 refers to the weight of the item
2 Give each web item a unique ID
3 Additional data element items
4 This parameter refers to the section, but it’s defined by the section for the context provider itself
There are a couple of shortcuts in this script that can be confusing. No return statements are used (as the result of the last statement is returned in groovy). So the collect returns the web items.

Example: My Top Issues

I often find I am distracted by email, instant messaging etc, and that JIRA doesn’t always get me back on track. This example is supposed to provide a quick cue by displaying the most important issues I should be working on, where most important is defined as the top five issues assigned to the current user in active sprints, ordered by rank. The finished result looks like:

my top issues

There are two parts to this - one is a web item provider which will run the query, fetching at most 5 results, and return them as web items. The other is a new section in the Issues menu to add them to. The web section is configured like so:

my top issues section

The web item provider:

my top issues provider

The code to generate the web items:

import com.atlassian.jira.bc.issue.search.SearchService
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.jql.parser.JqlQueryParser
import com.atlassian.jira.security.JiraAuthenticationContext
import com.atlassian.jira.util.velocity.VelocityRequestContextFactory
import com.atlassian.jira.web.bean.PagerFilter
import com.atlassian.plugin.web.api.model.WebFragmentBuilder

def jqlQueryParser = ComponentAccessor.getComponent(JqlQueryParser)
def query = jqlQueryParser.parseQuery("assignee = currentUser() and resolution is EMPTY and sprint in openSprints() order by rank")

def searchService = ComponentAccessor.getComponent(SearchService)
def jiraAuthenticationContext = ComponentAccessor.getComponent(JiraAuthenticationContext)
def searchResults = searchService.search(jiraAuthenticationContext.getLoggedInUser(), query, new PagerFilter(0, 5)) (1)

def velocityRequestContextFactory = ComponentAccessor.getComponent(VelocityRequestContextFactory)
def requestContext = velocityRequestContextFactory.getJiraVelocityRequestContext()
def baseUrl = requestContext.getBaseUrl()

searchResults.issues.collect { issue ->
    def issueLabel = "${issue.key} ${issue.summary}"

    String iconUrl = issue.issueTypeObject.iconUrl
    if (!iconUrl.startsWith("http://") && !iconUrl.startsWith("https://")) {
        iconUrl = baseUrl + iconUrl
    }
    new WebFragmentBuilder(50).
        id("sample-web-item-${issue.key.toLowerCase()}").
        label(issueLabel).
        title(issueLabel).
        styleClass("").
        addParam("class", "issue-link").
        addParam("data-issue-key", issue.getKey()).
        addParam("iconUrl", iconUrl).
        webItem("").
        url(baseUrl + "/browse/" + issue.getKey()).
        build()
}
1 Get at most 5 issues

For how-to questions please ask on Atlassian Answers where there is a very active community. Adaptavist staff are also likely to respond there.

Ask a question about ScriptRunner for JIRA, for for Bitbucket Server, or for Confluence.