Last updatedMay 6, 2019

Rate this page:

Creating a project template

Applicable:

Jira 7.0.0 and later.

Level of experience:

Intermediate. You should have completed at least one beginner tutorial before working through this tutorial. See the list of developer tutorials.

Time estimate:

It should take you approximately 1 hour to complete this tutorial.

Project template apps were originally supported in Jira 6.0 with the project-template module. However, Jira 6.0.7 introduces the project-blueprint plugin module that provides additional capabilities and is meant to substitute the project-template module. We strongly encourage you to use the project-blueprint module for project template app development, as described in this tutorial.

Overview of the tutorial

Jira project templates allow administrators to quickly create Jira projects with a predefined set of project configuration settings and properties. Jira comes with several built-in project templates, but you can create your own as Jira apps using the project-blueprint plugin module.

Besides hooking into the Jira project creation process, a project template app can define issue type schemes (with a set of custom issue types) and workflow schemes that link the issue types to Jira workflows.

This tutorial shows you how to build a project template app. Our project template will define a custom issue type scheme with three issue types and a workflow scheme with two imported workflows.

The completed Jira app will consist of the following components:

  1. Java classes encapsulating the app logic.
  2. Resources for display of the app UI (user interface).
  3. An app descriptor (XML file) to enable the plugin module in the Atlassian application.
  4. A configuration JSON file for your Project Template.
  5. A couple Jira workflow bundles for importing the workflows in your project template.

When you are finished, all these components are packaged in a single JAR file.

About these instructions

You can use any supported combination of OS and IDE to create this app. These instructions were written using IntelliJ IDEA 2017.3 on macOS Sierra. If you use another OS or IDE combination, you should use the equivalent operations for your specific environment.

This tutorial was last tested with Jira 7.7.1.

Before you begin

To complete this tutorial, you need to know the following:

  1. The basics of Java development: classes, interfaces, methods, how to use the compiler, and so on.
  2. How to create an Atlassian plugin project using the Atlassian Plugin SDK.
  3. How to use and administer Jira, particularly how to configure Jira projects.

App source

We encourage you to work through this tutorial. If you want to skip ahead or check your work when you have finished, you can find the app source code on Atlassian Bitbucket.

To clone the repository, run the following command:

1
git clone git@bitbucket.org:atlassian_tutorial/jira-project-templates-tutorial.git

Alternatively, you can download the source as a ZIP archive:

Step 1. Create the app project

In this step, you'll use the atlas SDK to generate stub code for your app. The atlas commands are part of the Atlassian Plugin SDK and automate much of the work of app development for you.

  1. Set up the Atlassian Plugin SDK and Build a Project if you have not done it yet.
  2. Open a Terminal and navigate to the directory where you want to create the project.
  3. To create an app skeleton, run the following command:

    1
    atlas-create-jira-plugin
  4. To identify your app, enter the following information.

    group-id

    com.example.plugins.tutorial

    artifact-id

    my-project-template

    version

    1.0-SNAPSHOT

    package

    com.example.plugins.tutorial

  5. Confirm your entries.

    1
    The SDK generates the project home directory with project files, such as the POM (Project Object Model definition file),

    stub source code, and app resources.

  6. Delete the test directories.

    1
    Setting up testing for your app isn't part of this tutorial. To delete the generated test skeleton,

    run the following commands:

    1
    2
    3
    4
    ``` bash
    rm -rf src/test/resources
    rm -rf src/test/java
    ```
  7. Delete the unneeded Java class files.

    1
    rm -rf src/main/java/com/example/plugins/tutorial
  8. Import the project to your favorite IDE.

Step 2. Tweak the POM

It's a good idea to familiarize yourself with the project configuration file, known as the POM. Among other functions, the POM declares project dependencies and controls build settings. It also contains descriptive information for your app. 

Tweak the metadata and add a dependency as follows:

  1. Navigate to the root folder of your project and open the pom.xml file.  

  2. Add your company or organization name and website URL to the organization element:

    1
    2
    3
    4
    <organization>
        <name>Example Company</name>
        <url>http://www.example.com/</url>
    </organization>
  3. To add a meaningful description, edit the project description element. For example:

    1
    <description>This is the Project Template plugin tutorial for Atlassian Jira.</description>

    The organization and description values you enter are propagated to the app descriptor file, atlassian.plugin.xml. From there, Jira uses them in the administration console display for your app.

  4. Under the dependencies element, add a dependency to the Project Templates API artifact:

    1
    2
    3
    4
    5
    6
    <dependency>
        <groupId>com.atlassian.jira.plugins</groupId>
        <artifactId>project-templates-api</artifactId>
        <version>6.2.0</version>
        <scope>provided</scope>
    </dependency>
  5. Save the file.

If working in an IDE, you need to refresh the dependencies in your project now.

Step 3. Add the plugin module to the app descriptor

Now you will add plugin modules to your app descriptor. The app descriptor is an XML file that identifies the app to Jira and defines the functionality that the app requires. We need to add two plugin modules: one for our project template and another for a web resource.

Project templates have their own module type called project-blueprint which takes care of the necessary configuration. Add it to your descriptor as follows:

  1. Navigate to src/main/resources and create a new soy folder.

  2. Create new Soy template MyProjectTemplate.soy with the following content:

    1
    2
    3
    4
    5
    6
    7
    8
    {namespace JIRA.Templates.ProjectTemplates.Tutorial}
    
    /**
     * Render the information page for My Project Template.
     */
    {template .renderMyProjectTemplateExplanation}
        <p>{getText('my.project.template.info.page.description')}</p>
    {/template}

    We will use this template for project info page.

  3. Open the atlassian-plugin.xml file and add the following as a child of the atlassian-plugin element: 

    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
    <atlassian-plugin ...>
      ...
        <web-resource key="my-project-template-resources" name="my-project-template Web Resources">
            <dependency>com.atlassian.auiplugin:ajs</dependency>
    
            <transformation extension="soy">
                <transformer key="soyTransformer"/>
            </transformation>
            <transformation extension="js">
                <transformer key="jsI18n"/>
            </transformation>
    
            <resource type="download" name="MyProjectTemplate.soy.js" location="/soy/MyProjectTemplate.soy"/>
    
            <resource type="download" name="images/" location="/images">
                <param name="content-type" value="image/png; charset=binary"/>
            </resource>
    
            <context>atl.general</context>
            <context>atl.admin</context>
        </web-resource>
    
        <project-blueprint key="my-project-template" weight="90">
            <label key="my.project.template.name"/>
            <projectTypeKey>business</projectTypeKey>
            <description key="my.project.template.description"/>
            <longDescription key="my.project.template.description.long"/>
    
            <infoPage soy-template="JIRA.Templates.ProjectTemplates.Tutorial.renderMyProjectTemplateExplanation" />
    
            <icon location="images/my-template-icon.png"/>
            <backgroundIcon location="images/my-template-background.png"/>
    
            <add-project>
                <hook class="com.example.plugins.tutorial.MyAddProjectHook"/>
                <descriptor file="/config/my-project-template-config.json"/>
            </add-project>
        </project-blueprint>
    
      ...
    </atlassian-plugin>

    At a minimum, you would only need to add the project-blueprint element, but since we're also adding an optional information page to the wizard, we need to define a web-resource element as well. Our web-resource element identifies the Soy template file that presents our text page in the wizard.

Let's take a closer look at the attributes and child elements of the project-blueprint app that we defined here.

Name*Description
key

The identifier of the plugin module. The key should be unique in the context of your app.

weight

Determines the order in which the project templates appear.

Default: 100

labelThe key attribute defines the localization key for the human-readable name of the plugin module. This name is used to identify the project template in the Project Templates dialog.
projectTypeKey(Jira 7.0+) All the project templates must provide the key for the type of the projects created with the template. Valid values for the project type key are "business",  "software", and  "service_desk".
descriptionThe key attribute defines the localization key for the human-readable short description of the plugin module. This description is used on the first page of the project templates dialog where all the available project templates are listed. 
longDescription

The key attribute defines the localization key for the human-readable long description of the plugin module. The long description is used on the right side of the Create Project form of the Project Templates dialog wizard. If no longDescription is specified, the short description is used. 

Default: description.

infoPage

The soy-template attribute refers to a Soy Template that renders a page in the Project Templates dialog. Typically, you would use this page to explain the characteristics of the Project Template to Jira administrator.

Make sure that the Soy Template is also declared as a web-resource in both atl.general and atl.admin contexts. The information page will be shown after the administrator selects your Project Template from the initial Project Templates selection dialog. If you do not define an infoPage element, the Project Templates wizard skips that step and goes directly to the Create Project form of the wizard.

Default: No information page.

icon

The location attribute defines an icon to be used when listing the available project templates in the selection screen of the Project Templates dialog. 

Default: default icon.

backgroundIcon

The location attribute defines the background image to use on the Create Project form of the wizard.

Default: default background image.

add-projectHolds the custom configuration instructions for the project that will be created.

*key, label, projectTypeKey, description are required.

The add-project element also holds a number of configuration parameters that are specific for the actual project creation.

NameDescription
hook

The class attribute refers to the Java class that implements the AddProjectHook interface. This allows project templates to hook into the validation and configuration of Jira projects.

descriptor

The file attribute refers to a JSON file which defines parts of the configuration for the project.

Step 4. Generate workflow bundles

Project templates can incorporate one or more Jira workflows as part of their project configuration. To incorporate a workflow in your project template, you first need to define the workflow in an existing Jira project, and then use the workflow sharing feature to export the workflow from there.

Exporting a workflow results in a Jira workflow bundle (.jwb) file, one for each exported workflow. You can then use the .jwb file in your project template app. Keep in mind that an exported Jira workflow doesn't include custom fields, post functions, validators, and conditions. If you want your workflow to have this functionality when using a project template, you can use the AddProjectHook  to create it. 

  1. To get a workflow bundle file for the app, do one of the following:

    1. Create a workflow export bundle of the workflow you want to use in your project by following the instructions for exporting a workflow.
    2. Get the workflow bundles we've built for you. The bundles are in the src/main/resources/wfb/ directory of the Bitbucket repository for this tutorial
  2. In a new directory under your src/main/resources/wfb, save the workflow bundle file. 

Step 5. Set up the JSON configuration file

The JSON configuration file allows you to declare a number of configuration options for your project template: 

  • Issue types
  • Issue type scheme
  • Workflows
  • Workflow type scheme
  • The mapping of issue types to workflows

The JSON configuration file for a project template is optional and is needed only if the hook element is declared in the  add-project element of a project-blueprint plugin module. In this step, we add one.

  1. Navigate to src/main/resources/config and create a new JSON file named my-project-template-config.json.
  2. Add the following code to the file: 

    my-project-template-config.json

    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
    {
        "issue-type-scheme":
        {
            "name": "my.project.template.issuetype.scheme.name",
            "description": "my.project.template.issuetype.scheme.description",
            "issue-types": [
                {
                    "key": "issueType1",
                    "name": "New Feature",
                    "description": "A new feature of the product, which has yet to be developed.",
                    "icon": "/images/icons/newfeature.png",
                    "workflow": "wf1"
                },
                {
                    "key": "issueType2",
                    "name": "Bug",
                    "description": "A problem which impairs or prevents the functions of the product.",
                    "icon": "/images/icons/bug.png"
                },
                {
                    "key": "issueType3",
                    "name": "Sub-Task",
                    "description": "The sub-task of the issue",
                    "icon": "/images/icons/subtask_alternate.png",
                    "sub-task": true,
                    "workflow": "wf2"
                }
            ]
        },
        "workflow-scheme":
        {
            "name": "my.project.template.workflow.scheme.name",
            "description": "my.project.template.workflow.scheme.description",
            "default-workflow": "wf1",
            "workflows": [
                {
                    "key": "wf1",
                    "name": "my.project.template.workflow.wf1.name",
                    "workflow-bundle": "/wfb/Issue-Tracking-Workflow.jwb"
                },
                {
                    "key": "wf2",
                    "name": "my.project.template.workflow.wf2.name",
                    "workflow-bundle": "/wfb/Software-Development-Workflow.jwb"
                }
            ]
        }
    }

In my-project-template-config.json and atlassian-plugin.xml we defined few icons. Download them from Bitbucket and place under src/main/resources/images.

Let's take a closer look at the meaning of the configuration options here: 

  • The values of name and description attributes of issue-type-scheme and workflow-scheme refer to i18n keys.
  • The key attribute of an issue type only serves as an internal identifier within the project templates infrastructure. 
  • The icon attribute of an issue type refers to an icon location in the src/main/resources directory of your app.
  • The sub-task attribute of an issue type lets you declare whether the issue type is a normal issue type (default) or a sub-task.
  • If the issue types that are declared in the issue-type-scheme don't exist in the Jira instance, they are created using the declared configuration.
  • The key attribute of a workflow can be used to map issue types to workflows, or to declare the default-workflow  for a workflow-scheme.
  • The default-workflow attribute of a workflow-scheme lets you define which workflow to use if an issue type is used without an explicit workflow mapping. The value refers to the key attribute of a workflow.
  • The workflow-bundle of a workflow refers to a Jira workflow bundle location in the src/main/resources  directory of your app.

Step 6. Write Java class

In this step you write the Java class. This example simply creates a basic project which checks whether the project key is not "TEST". When the project is successfully created, it redirects the user from the Create project dialog to the Issues Browser.

  1. Navigate to src/main/java/com/example/plugins/tutorial and create a new class named MyAddProjectHook.
  2. Add the following code to the class:

    MyAddProjectHook

    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
    package com.example.plugins.tutorial;
    
    import com.atlassian.jira.project.template.hook.AddProjectHook;
    import com.atlassian.jira.project.template.hook.ConfigureData;
    import com.atlassian.jira.project.template.hook.ConfigureResponse;
    import com.atlassian.jira.project.template.hook.ValidateData;
    import com.atlassian.jira.project.template.hook.ValidateResponse;
    
    public class MyAddProjectHook implements AddProjectHook
    {
        @Override
        public ValidateResponse validate(final ValidateData validateData)
        {
            ValidateResponse validateResponse = ValidateResponse.create();
            if (validateData.projectKey().equals("TEST"))
            {
                validateResponse.addErrorMessage("Invalid Project Key");
            }
    
            return validateResponse;
        }
    
        @Override
        public ConfigureResponse configure(final ConfigureData configureData)
        {
            return ConfigureResponse.create();
        }
    }

Notice that the new class implements the AddProjectHook interface. The interface defines two methods:

  • validate() allows your app to validate the parameters to be used for creating the project. It takes the parameters as an argument, and can return errors in the ValidateResponse object. The errors, if any, are merged with any other errors resulting from Jira's project validation and are returned to the client.
  • configure() performs setup actions for the project post-creation. It takes the new ConfigureData as an argument, which holds all the created entities (project, workflow scheme, workflows, issue type scheme, and issue types).
    The configure() function can be used for a wide variety of configuration options. For example, you can use this to create Workflow Post Functions, Resolutions, and more.

Step 7. Add the i18n keys

In a couple of places we referenced i18n keys. We need to provide values for those i18n keys in the i18n properties file.

  1. Navigate to src/main/resources and open the my-project-template.properties file.
  2. Add the following lines:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #put any key/value pairs here
    my.project.template.name=My Project Template
    my.project.template.description=This is my custom Project Template
    my.project.template.description.long=This custom Project Template will create a new Project with customized workflows and issue types.
    my.project.template.info.page.description=Explain the configurations specifics of your template here.
    my.project.template.issuetype.scheme.name=My Project Template Issue Type Scheme
    my.project.template.issuetype.scheme.description=This is my Issue Type Scheme
    my.project.template.workflow.scheme.name=My Project Template Workflow Scheme
    my.project.template.workflow.scheme.description=My Project Template Workflow Scheme
    my.project.template.workflow.wf1.name=My Workflow 1
    my.project.template.workflow.wf2.name=My Workflow 2
  3. To ensure that this file is used for translations, make sure the following line is in your atlassian-plugin.xml:

    1
    2
    3
    ``` xml
    <resource type="i18n" name="i18n" location="my-project-template"/>
    ```

Step 8. Build, install, and run the app

Now you're ready to try out the new project app:

  1. Open a Terminal and navigate to the project root directory.
  2. Run the following SDK command:

    1
    atlas-run

    This builds your app code, starts a Jira instance, and installs your app. This could take a few minutes.

  3. Find the Jira home page URL in the Terminal output and open it in your browser.

  4. Log in with the default admin/admin.
  5. Create a new project based on the My Project Template template. This is the template you created. 
  6. Check that the information page is shown.
  7. Enter a project name and a key, as usual.

  8. Click Submit. Confirm that you are redirected to the issue browser page.

Congratulations, that's it!

Have a treat!

Next steps

To learn more about the customizing projects in Jira, go to these tutorials:

Rate this page: