Adding javascript web-resource for use in velocity template used by servlet

John Campbell June 4, 2019

Hi,

I'm developing a Jira Service Desk plugin and need to provide an admin configuration form. 

I've followed  this tutorial and have the following servlet in my plugin.xml file:

 

<servlet key="admin-servlet" class="org.atlassian.tutorial.actions.AdminServlet">
<url-pattern>/test/admin</url-pattern>
</servlet>

 

The class AdminServlet uses the template renderer to return a velocity template:

response.setContentType("text/html;charset=utf-8");
renderer.render("/templates/react-panel.vm", response.getWriter());

and redirects the user to the login page if they are not admin or not logged in.

The template renders ReactJS elements provided by a web-resource:

<web-resource key="component-embeddable-pack"> 
<resource type="download" name="component.pack.js" location="/client/component.pack.js"/>
</web-resource>

The template itself contains:

<div id="create-article-form">React code should render here!</div>
$webResourceManager.requireResource("org.atlassian.tutorial.react-component-test:component-embeddable-pack")

and this template renders the React components correctly when part of a web-panel:

<web-panel name="react-panel" i18n-name-key="react--panel.name" key="react--panel" location="atl.jira.view.issue.left.context" weight="50"> 
<description key="react--panel.description">A react-panel Plugin</description>
<resource name="view" type="velocity" location="templates/react-panel.vm"/>
</web-panel>

which I created earlier for testing purposes. 

 

So, back to the admin page - when I visit `http://localhost:2990/jira/plugins/servlet/test/admin`

the template is displayed, the redirect to login page works perfectly, but the React component is not rendered. If I console.log the React code I can see that the method to mount the component isn't called at all. So it looks like the template doesn't see the web-resource containing the React code despite it being required inside the template. Do I need to require the web-resource elsewhere or am I missing something else?

 

Update: I've got this working, so for the benefit of anyone having similar issues I'll try to summarise what I did.

 

The velocity template looks like this:

<html>
<head>
<title>Configuration</title>
<meta name="decorator" content="atl.admin" />
<meta name="admin.active.section" content="plugin-admin-config-link" />
</head>
<body>
<h1>Plugin Configuration</h1>
<div id="create-article-form">React code should render here</div>
</body>
</html>

There's a web resource which exposes the ReactJS bundle:

<web-resource key="component-embeddable-pack"> 
<resource type="download" name="component.pack.js" location="/client/component.pack.js"/>
<context>atl.admin</context>
</web-resource>

To create the admin menu item I have a web-section:

<web-section key="admin_handler_config_section" location="admin_plugins_menu">
<label key="Plugin - Admin Configuration" />
</web-section>

and a web item which references it so that the menu item appears in that section

<web-item key="plugin-admin-config-link"
section="admin_plugins_menu/admin_handler_config_section">
<label key="Plugin Configuration" />
<link linkId="handler.plugin.configuration.link" key="plugin-configuration">/plugins/servlet/aws/admin</link>
</web-item>

 The web-item link is the path to the servlet which serves up the template

<servlet key="admin-servlet" class="org.atlassian.tutorial.actions.AdminServlet">
<url-pattern>/aws/admin</url-pattern>
</servlet>

The class that implements the servlet AdminServlet uses the pageBuilderService to pull in the component-embeddable-pack web-resource:

pageBuilderService.assembler().resources()
.requireWebResource("org.atlassian.tutorial.react-component-test:component-embeddable-pack")
.requireContext("atl.admin");
response.setContentType("text/html;charset=utf-8");
renderer.render("/templates/react-panel.vm", response.getWriter());

You declare the PageBuilderService like this:

@ComponentImport
private PageBuilderService pageBuilderService;

and in the constructor:

this.pageBuilderService = pageBuilderService;

Hope this helps someone!

1 answer

0 votes
Adria Alonso
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 15, 2019

Thank you for sharing this, it helped me out today!!

Suggest an answer

Log in or Sign up to answer