Reporter template syntax

This article addresses the specifics of a Reporter template.

For a general introduction to Liquid, refer to this article.

Single vs Multiple issue report templates

While preparing a template, the only object you can directly access is either
  • issue (single issue template) or
  • issues (the array of issues included in the report when preparing a multi-issue template).

When preparing a multi-issue template, you can iterate through every issue in the list with:

{% for issue in issues %}
(Access contents of each issue)
{% endfor %}

Access issue contents

Issue objects

The syntax to acces a specific attribute of an object is {{object.attribute}}.

Below you will find a list of available objects, as well as their respective sets of accessible attributes. Attributes in bold represent further objects with attributes of their own.

- issue
id subject description visible? closed? estimated_hours
start_date due_date overdue? done_ratio priority spent_hours
is_private? closed_on updated_on created_on link total_spent_hours
url author assignee tracker status total_estimated_hours
category version time_entries parent color story_points
project subtasks notes journals* tags day_in_state

* journals refers to the list of notes of the issue, it is an array of objects of type journal

- array (issues, subtasks, users... are objects of this type)
all visible each size
- project
id identifier name is_public description short_description
link visible? active? start_date due_date completed_percent
url archived? overdue? issues users subprojects
- user (author, assignee are objects of this type)
id name firstname lastname mail active? admin?
logged? language avatar permissions groups projects
- time_entry
id hours comments spent_on tyear tmonth tweek
visible? updated_on created_on user issue activity
- journal
created_on user notes
- checklist_item
id_done subject

FAQ: "How to get days?" ---> It is done by time_entry.spent_on.


  • With {{issue.project.users}} you reference the array of all users involved in the project this issue belongs to.
  • To print a list of all issue notes you can use
    {% for journal in issue.journals.all %}
        {% if journal.notes != ''  %}
            <em>{{journal.created_on | date: "%a, %b %d, %y"}} - {{}}</em> {{journal.notes | textilize }}
        {% endif %}   
    {% endfor %}
    ... producing the following output:
    Sun, Dec 09, 18 - User One
    (Comment of User One...)
    Mon, Dec 10, 18 - User Two
    (Comment of User Two...)
    The {% if journal.notes != '' %} check is necessary to select only entries that actually represent a comment and to ignore entries that contain only changes to some issue field.
  • With {{issue.total_spent_hours | round: 2 }} you will display the total spent hours rounded to 2 decimal places.
  • With{{issue.url}} you can print an URL to the issue.

Issue custom fields

To access the content of a custom field, use
{{issue | custom_field: "custom_field_name"}}.

You can also iterate through all custom fields with
{% assign custom_fields = issue | custom_fields%}
{% for field in custom_fields %}
<p><b>{{field}}:</b> {{issue | custom_field: field}}</p>
{% endfor %}

Note: 'issue' here is a an object of type issue. When preparing a multi-issue template there is no such object initially, rather the array 'issues'. You can use this loop to refer to each issue separately.

CSS styling

To add CSS styling direct into the template use the <style> tag as you would in an HTML document.

Import a template

Alternatively, you can a template. You cannot import a template that has the same name as an existing one unless you mark Rewrite existed. In that case, the existing one will be replaced by the import.

Note: You can try out our sample templates. Just download the .yml template file and import it into your Redmine.

Was this article helpful? Yes  No
1710 from 1732 found this helpful