Last updatedSep 4, 2020

Rate this page:

Setting up the CSE page bootstrapper

Client-side Extensions page bootstrapper is an Atlassian plugin that provides the web-page module descriptor which makes it possible to create a page using the CSE APIs.

The CSE webpack plugin will generate a web-page definition when declaring page extensions.

CSE page extension is a stand-alone solution that only relies on CSE page bootstrapper, so you can start creating pages even if a product doesn't include CSE yet.

Under the hood, the page bootstrapper uses a combination of existing primitives like Servlet and Soy templates to generate a route for your page, all under the CSE APIs to accelerate frontend development.

Before you start using web-page, you first need to add and configure the CSE page bootstrapper for your plugin as follows:

1. Add Maven dependencies

In your pom.xml file:

  • Add the atlassian-clientside-extensions-page-bootstrapper artifact as a dependency of your plugin. This dependency is NOT provided by the products.
  • Verify your plugin depends on com.atlassian.soy.soy-template-renderer-api, and its scope is provided.
  • Verify your plugin depends on com.atlassian.sal.sal-api, and its scope is provided.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<project>
    <dependencies>
        <!-- CSE page bootstrapper -->
        <dependency>
            <groupId>com.atlassian.plugins</groupId>
            <artifactId>atlassian-clientside-extensions-page-bootstrapper</artifactId>
            <version>${cse.version}</version> <!-- >= 1.2.0 -->
        </dependency>

        <!-- CSE page bootstrapper dependencies -->
        <dependency>
            <groupId>com.atlassian.soy</groupId>
            <artifactId>soy-template-renderer-api</artifactId>
            <version>${soy.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.sal</groupId>
            <artifactId>sal-api</artifactId>
            <version>${sal.version}</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

2. Import clientsideextensions package and pluginArtifact

In your pom.xml file, find your declaration of the Maven plugin for the product you're targeting (e.g: bitbucket-maven-plugin), and:

  • Import the com.atlassian.plugin.clientsideextensions package.
  • Include the atlassian-clientside-extensions-page-bootstrapper plugin artifact.
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
<project>
    <plugins>
        <plugin>
            <groupId>com.atlassian.maven.plugins</groupId>
            <artifactId>bitbucket-maven-plugin</artifactId> <!-- or the maven plugin of the product you're targeting -->
            <version>${amps.version}</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
                    <Import-Package>
                        com.atlassian.plugin.clientsideextensions, <!-- import the package -->
                        *
                    </Import-Package>
                </instructions>
                <pluginArtifacts>
                    <pluginArtifact> <!-- include the pluginArtifacts -->
                        <groupId>com.atlassian.plugins</groupId>
                        <artifactId>atlassian-clientside-extensions-page-bootstrapper</artifactId>
                        <version>${cse.version}</version>
                    </pluginArtifact>
                </pluginArtifacts>
            </configuration>
        </plugin>
    </plugins>
</project>

3. Configure OSGi imports

Lastly, you'll need to create a Java class to import the necessary OSGi services as Spring proxy beans.

  • Create a Java class called ComponentImports with this code:
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
// in src/main/java/your/package/name/ComponentImports.java

package your.package.name;

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.sal.api.message.I18nResolver;
import com.atlassian.soy.renderer.SoyTemplateRenderer;

/**
 * This class is never instantiated, it serves only to cause the necessary OSGi services to be imported as Spring proxy beans.
 */
@SuppressWarnings("unused")
final class ComponentImports {

    // Needed by ExtensionPageServlet to translate the title of the `web-page` plugin module
    @ComponentImport
    private final I18nResolver i18nResolver;

    // Needed by ExtensionPageServlet to render the Soy template of the `web-page` plugin module
    @ComponentImport
    private final SoyTemplateRenderer soyTemplateRenderer;

    private ComponentImports() {
        throw new UnsupportedOperationException("Not for instantiation");
    }
}

Final configuration

Your pom.xml should look like this:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<project>
    <groupId>your.group.id</groupId>
    <artifactId>your-artifact-id</artifactId>
    <version>1.0.0-SNAPSHOT</version> <!-- your plugin's version -->
    <packaging>atlassian-plugin</packaging>

    <dependencies>
        <!-- CSE page bootstrapper -->
        <dependency>
            <groupId>com.atlassian.plugins</groupId>
            <artifactId>atlassian-clientside-extensions-page-bootstrapper</artifactId>
            <version>${cse.version}</version> <!-- >= 1.2.0 -->
        </dependency>

        <!-- CSE page bootstrapper dependencies -->
        <dependency>
            <groupId>com.atlassian.soy</groupId>
            <artifactId>soy-template-renderer-api</artifactId>
            <version>${soy.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.atlassian.sal</groupId>
            <artifactId>sal-api</artifactId>
            <version>${sal.version}</version>
            <scope>provided</scope>
        </dependency>

        <!-- ... other dependencies ... -->
    </dependencies>

    <plugins>
        <plugin>
            <groupId>com.atlassian.maven.plugins</groupId>
            <artifactId>bitbucket-maven-plugin</artifactId> <!-- or the maven plugin of the product you're targeting -->
            <version>${amps.version}</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Atlassian-Plugin-Key>${atlassian.plugin.key}</Atlassian-Plugin-Key>
                    <Import-Package>
                        com.atlassian.plugin.clientsideextensions, <!-- import the package -->
                        *
                    </Import-Package>
                    <Spring-Context>*</Spring-Context>
                </instructions>
                <pluginArtifacts>
                    <pluginArtifact> <!-- include the pluginArtifacts -->
                        <groupId>com.atlassian.plugins</groupId>
                        <artifactId>atlassian-clientside-extensions-page-bootstrapper</artifactId>
                        <version>${cse.version}</version>
                    </pluginArtifact>
                </pluginArtifacts>
            </configuration>
        </plugin>

        <!-- ...other plugins... -->
    </plugins>

    <properties>
        <cse.version>1.2.0</cse.version> <!-- >= 1.2.0 -->
        <soy.version>5.0.0</soy.version>
        <sal.version>4.0.0</sal.version>
    </properties>
</project>

And the Java class for OSGi imports

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
// in src/main/java/your/package/name/ComponentImports.java

package your.package.name;

import com.atlassian.plugin.spring.scanner.annotation.imports.ComponentImport;
import com.atlassian.sal.api.message.I18nResolver;
import com.atlassian.soy.renderer.SoyTemplateRenderer;

/**
 * This class is never instantiated, it serves only to cause the necessary OSGi services to be imported as Spring proxy beans.
 */
@SuppressWarnings("unused")
final class ComponentImports {

    // Needed by ExtensionPageServlet to translate the title of the `web-page` plugin module
    @ComponentImport
    private final I18nResolver i18nResolver;

    // Needed by ExtensionPageServlet to render the Soy template of the `web-page` plugin module
    @ComponentImport
    private final SoyTemplateRenderer soyTemplateRenderer;

    private ComponentImports() {
        throw new UnsupportedOperationException("Not for instantiation");
    }
}

Rate this page: