So it turns out you can use SOY templates in JIRA webwork actions, but its not a straightforward switch.
Soy
First you need to convert your template to soy:
{namespace Magical.templates}
/**
* Render the main UI
* @param something
*/
{template .main}
<html>
...
</html>
{/template}
Web-resource
Then add a web-resource to declare your soy file:
<web-resource key="action-templates">
<resource type="soy" name="does-not-matter" location="somewhere/magic-action.soy"/>
</web-resource>
Webwork
Then adjust the webwork action to refer to it:
<webwork1 key="some-magic" class="java.lang.Object">
<actions>
<action name="com.example.MagicAction" alias="Magic">
<view type="soy" name="input">:action-templates/Magical.templates.main</view>
</action>
</actions>
</webwork1>
Notice the view refers to the web-resource module key: :action-templates - this is short form for my-plugin-key:action-templates, followed by the fully namespaced template name after a slash. We don't need to know the file location or resource name here.
Watch it fail
Then give it a whirl, and watch it fail ;)
Annotate like crazy
We don't get any parameters passed to the template at all by default, which in someways is good, but it means extra work adapting your action.
You no longer have an $action parameter either.
To pass data into the template you need to annotate the methods in your action with @ActionViewData, eg:
@ActionViewData
public String getSomething() {
return ...;
}
The data from these methods is gathered prior to rendering, and not called on-demand, as velocity does. Also if you want to get data from a method higher in the inheritance hierarchy you'll need to override it and annotate it, eg:
@ActionViewData
@Override
public String getReturnUrl() {
return super.getReturnUrl();
}
You can no longer call arbitrary methods from your action, @ActionViewData only supports methods that return something and take no parameters.
Although you can return any object from these methods and a soy mapper will handle resolving keys to method calls, as best as it can. If you need more control over the process, either format and return new data, or use a SoyDataMapper - I haven't tried this yet though.
@ActionViewData does allow you to specify an alternative parameter name for the data return by the method, and you can also limit which views the data will be collected for.
@ActionViewDataMappings is similar but allows specifying of several action views.
I18n
Wherever you used to do this:
${i18n.getText('foo')}
you'll do:
{getText('foo')}
but BEWARE, the argument has to be a literal string, this will not work:
{getText($myI18nKey)}
you'll have to resolve dynamic i18n keys in your action beforehand.
- 09 Oct 2018 » A strange bug on AWS Lambda
- 17 Jan 2018 » How to run Karma tests in browsers in Docker
- 07 Dec 2017 » Switching from Javascript to Typescript
- 30 Oct 2017 » Fun with React event handlers
- 17 Jul 2017 » Switching from Groovy to Java
- 24 May 2017 » Useful Git Aliases
- 27 Mar 2017 » Practical Ratpack Promises
- 03 Nov 2016 » Custom Content in Forms for Confluence Connect
- 04 Oct 2016 » Checking user permissions from REST calls
- 30 Sep 2016 » Using the reflection API in Confluence
- 28 Sep 2016 » Creating a custom Confluence Blueprint
- 06 Sep 2016 » ReactJS in Forms for Confluence Connect
- 25 Apr 2016 » Migrating to ES6 in Atlassian Add-ons
- 17 Mar 2016 » All kinds of things I learnt trying to performance test against Fisheye/Crucible
- 24 Dec 2015 » Adaptavist’s Holiday Gift of Atlassian Deployment Automation
- 17 Dec 2015 » Getting a Custom Field value safely
- 07 Dec 2015 » Putting Google Analytics to work with plugins for Confluence
- 02 Dec 2015 » Devoxx Voting, A retrospective
- 25 Nov 2015 » Some things I've learnt about SingleSelect
- 15 Oct 2015 » Using SOY for JIRA actions
- 26 Sep 2015 » Object Reflection in Groovy
- 22 Sep 2015 » Introducing Adaptavist Labs