Client Web Section Plugin Module

Introduction

Client Web Sections are part of Bitbucket Server's Client Web Fragment family of modules. They parallel the functionality of Web Sections, but are rendered dynamically in the browser.

Please see the guide on adding to the pull request overview for an example of how they can be used.

Configuration

The root element for the Client Web Section plugin module is client-web-section. It allows the following attributes and child elements for configuration:

Attributes

NameRequiredDescriptionDefault
keyYesThe identifier of the plugin module. This key must be unique within the plugin where it is defined.N/A
nameThe human-readable name of the plugin module. I.e. the human-readable name of the web section.N/A
locationYesLocation into which this web section should be placed.N/A
weightDetermines the order in which web sections appear. Sections are displayed in order of ascending weight. The 'lightest' weight is displayed first, the 'heaviest' weight sink to the bottom.1000

Elements

NameRequiredDescriptionDefaultDefault type
condition Defines a condition (evaluated on the server during page render) that must be satisfied for the web section to be displayed. For details on using conditions, see Web Fragments - Conditions. N/AN/A
conditions Defines the logical operator type to evaluate its condition elements (evaluated on the server during page render). By default 'AND' will be used. N/AN/A
context-provider Defines the data that will be passed to your client-web-section's "js" type fields. This acts similarly to how it would on a normal web-section (see Web Section - Context provider), but there will be no incoming context object passed to the ContextProvider. N/AN/A
client-condition

Defines a JS function that is evaluated before each display of the client-web-section. if the function returns true, the client-web-section will be displayed.

NOTE: client-conditions should not be used for hiding sensitive data. See the Security Note on client web fragments for details.

N/Ajs
client-context-provider Defines a JS function for transforming the data that will be passed to your client-web-section's "js" type fields. N/Ajs
dependencyDefines a Web Resource that this client-web-section depends on.N/AN/A
descriptionThe description of the plugin module. The 'key' attribute can be specified to declare a localisation key for the value instead of text in the element body. I.e. the description of the web section.N/AN/A
labelThe textual representation of the link. The 'key' attribute can be specified to declare a localisation key for the value instead of text in the element body.N/Atext
paramParameters for the plugin module. Use the 'key' attribute to declare the parameter key, then specify the value in either the 'value' attribute or the element body. This element may be repeated. These will be merged into the context.N/Atext
tooltipThe text representation used for mouse-over text for the link. Note that this value may be ignored in some situations.N/Atext

Example

Here is an example atlassian-plugin.xml file containing a client web section and its dependencies:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<atlassian-plugin name="My Plugin" key="example.plugin" plugins-version="2">
    <plugin-info>
        <description>A basic plugin</description>
        <vendor name="My Company" url="http://www.mycompany.com"/>
        <version>1.0</version>
    </plugin-info>

    <client-web-section key="myWebSection" name="A Web Section" location="web-section-location" weight="100">
        <context-provider class="com.mycompany.example.plugin.PrivateWidgetsContextProvider" />
        <client-condition>WidgetManager.hasWidgets</client-condition>
        <label type="js"><![CDATA[
            function(ctx) {
                switch (ctx.widgets.length) {
                    case 0: return "No widgets";
                    case 1: return "1 repository widget";
                    default:
                        return ctx.widgets.length + " repository widgets";
                }
            }
        ]]></label>
        <dependency>example.plugin:widget-manager-js</dependency>
    </client-web-section>

    <web-resource key="widget-manager-js" name="JS for managing widgets">
        <resource type="download" name="widget-manager.js" location="js/widget-manager.js" />
    </web-resource>
</atlassian-plugin>

And the corresponding com.mycompany.example.plugin.PrivateWidgetsContextProvider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.mycompany.example.plugin;

import com.atlassian.plugin.web.ContextProvider;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.google.common.collect.ImmutableMap;

public class PrivateWidgetsContextProvider implements ContextProvider {

    private WidgetService widgetService;

    public PrivateWidgetsContextProvider(WidgetService widgetService) {
        this.widgetService = widgetService;
    }

    @Override
    public void init(Map<String, String> params) throws PluginParseException {
    }

    @Override
    public Map<String, Object> getContextMap(Map<String, Object> context) {
        return ImmutableMap.<String, Object>builder()
                .put("widgets", widgetService.getWidgetsForUser((ApplicationUser) context.get('currentUser')))
                .build();
    }
}

And the corresponding widget-manager.js:

1
2
3
4
5
6
var WidgetManager = {
    hasWidgets : function(context) {
        var widgets = context.widgets;
        return widgets && widgets.length > 0;
    }
};