Wiki source code of JIRA Macro Extension Points

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

Hide last authors
Vincent Massol 1.1 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.
Vincent Massol 3.3 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}}
Vincent Massol 1.1 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