Wiki source code of JIRA Macro Extension Points

Last modified by Vincent Massol on 2026/08/04 21:49

Show last authors
1 Five Component roles make up the extensible surface of the JIRA Macros. Registering an implementation under the right hint is all that is needed for a page author to reach it through a Macro parameter.
2
3 |=Role|=Hint|=Contributes
4 |##JIRADataSource##|The value of the ##source## Macro parameter|A new way of turning the Macro content into a set of issues. The built-in hints are ##list## and ##jql##.
5 |##JIRADisplayer##|The value of the ##style## Macro parameter|A new way of rendering a set of issues. The built-in hints are ##table##, ##list## and ##enum##.
6 |##JIRAFieldDisplayer##|A field id, or ##type/<field type>##|A new way of rendering one field, or every field of one type. Looked up by field id first, then by field type, then falling back to the default implementation.
7 |##JIRAMacroTransformation##|Any|{{version product="JIRA" since="11.0.0"}}A rewriting of the blocks a JIRA Macro produced.{{/version}}
8 |##JIRAAuthenticatorFactory##|The id of an authentication scheme|{{version product="JIRA" since="11.0.0"}}A new way of authenticating against a JIRA instance. Covered by [[Extend JIRA Authentication>>doc:documentation.extensions.dev.jira.extend-authentication.WebHome]].{{/version}}
9
10 The first three roles live in the ##org.xwiki.contrib.jira.macro## package of the JIRA Macro module, the last two in ##org.xwiki.contrib.jira.macro## and ##org.xwiki.contrib.jira.config## respectively. Issues are handled as JDOM ##Element## instances, because the ##jira## Macro reads JIRA's XML search view rather than a typed model.
11
12 == Adding a Source ==
13
14 {{code language="java"}}
15 @Role
16 public interface JIRADataSource
17 {
18 Collection<Element> getData(String macroContent, JIRAMacroParameters parameters)
19 throws MacroExecutionException, JIRABadRequestException;
20 }
21 {{/code}}
22
23 Throw ##JIRABadRequestException## when JIRA itself rejected the request, so that the Macro can report JIRA's own messages instead of a generic failure, and ##MacroExecutionException## for anything else.
24
25 == Adding a Style ==
26
27 {{code language="java"}}
28 @Role
29 public interface JIRADisplayer
30 {
31 List<Block> display(Collection<Element> issues, JIRAMacroParameters parameters);
32
33 @Unstable
34 default List<Block> display(Collection<Element> issues, JIRAMacroParameters parameters,
35 MacroTransformationContext context)
36 {
37 return display(issues, parameters);
38 }
39 }
40 {{/code}}
41
42 Implement the three-argument method when the rendering depends on the context, for instance to render differently inline; its default implementation delegates to the two-argument one.
43
44 == Adding a Field Renderer ==
45
46 {{code language="java"}}
47 @Role
48 public interface JIRAFieldDisplayer
49 {
50 List<Block> displayField(JIRAField field, Element issue, JIRAMacroParameters parameters);
51 }
52 {{/code}}
53
54 Register the Component under the id of the field to render one particular field, or under ##type/<field type>## to render every field declaring that type. Overriding a field that already has a renderer of its own, such as ##status##, means registering a Component override under that field id.
55
56 == Transforming the Result of a Macro ==
57
58 Transformations apply to the ##jira##, ##jiraCount## and chart Macros alike. Components are looked up by the parameter type ##P##, so a transformation applies to the Macros whose parameter class it names.
59
60 {{code language="java"}}
61 @Role
62 public interface JIRAMacroTransformation<P>
63 {
64 default List<Block> transform(List<Block> blocks, P parameters,
65 MacroTransformationContext context, JIRAServer jiraServer, String macroName)
66 {
67 return blocks;
68 }
69 }
70 {{/code}}
71
72 A transformation that fails is logged and skipped, and the Macro renders its untransformed blocks.
73
74 == Passing Configuration to a Component ==
75
76 The ##parameters## Macro parameter carries a comma-separated list of ##name=value## pairs, which every source, displayer and field renderer receives through its ##JIRAMacroParameters## argument. Prefix the names so that they cannot collide:
77
78 |=Prefix|=For|=Example
79 |##source.<hint>.*##|A ##JIRADataSource##|##source.jql.something##
80 |##display.<hint>.*##|A ##JIRADisplayer##|##display.table.something##
81 |##field.<hint>.*##|A ##JIRAFieldDisplayer##|##field.url.label##

Get Connected