Wiki source code of JIRA Macro Extension Points
Last modified by Vincent Massol on 2026/08/04 21:49
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 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## |