# Notification Template Language Reference

This reference lists the variables, properties, methods, and helper APIs that are currently exposed to YouTrack notification templates.

The exact set of variables that you can use depends on the template that you edit. The Available Variables panel in the editor shows the variables that are supported for the current template.

> **Note:**
> Notification templates use Freemarker object access rules. In most cases, you can access object members as properties, for example `issue.id` or `issue.url`. Existing templates may also use getter-style expressions like `issue.getId()`. Both forms can refer to the same underlying value.

## Common Examples

Use the following examples as a quick reference for common notification template tasks.

```HTML
@notificationtemplatesolidhtml
            ${issue.id}
            <a href="${issue.url}">${issue.id}</a>
            ${comment.text}
            <@markup><#noescape>${comment.text}</#noescape></@markup>
            <#list issue.fields as field>${field.name}: ${field.value}</#list>
```

Older templates may use expressions like `${issue.getId()}` and `${Utils.getUrl(issue)}` for the same values.

## Local Variables

Local variables can be used but not changed by the user. These variables are predefined and read-only.

| Local Variable | Type | Description |
| --- | --- | --- |
|  `header`  |  `string`  |    The `header` of a notification. This is a short label that identifies the notification type. Common values include `Created`, `Assigned`, `Updated`, `Resolved`, `Commented`, `Voted`, `Tagged`, `Untagged`, `Backup`, and `Simple`. Additional values are used for specific notification types.     This variable is used in the default email subject template.    |
|  `from`  |  `User`  |  Represents the sender of the notification.  |
|  `to`  |  `User`  |  Represents the recipient of the notification.  |
|  `application.name`  |  `string`  |  Evaluates to `YouTrack`.  |
|  `application.version`  |  `string`  |  Evaluates to the current version.  |
|  `application.build`  |  `string`  |  Evaluates to the current build number.  |
|  `issue`  |  `Issue`  |  Represents the issue that triggered the notification.  |
|  `article`  |  `Article`  |  Represents the article that triggered the notification. This variable is available in article notifications.  |
|  `change`  |  `Change`  |  Represents the change that triggered the notification. Use this variable to access the author, timestamps, and events that are included in a digest.  |
|  `changes`  |  `Collection<Change>`  |  Contains multiple changes for cluster digest notifications.  |
|  `comment`  |  `Comment`  |  Represents a posted or updated comment.  |
|  `commentFromReply`  |  `boolean`  |  Indicates that the outgoing helpdesk comment was created from an email reply. This variable is used in helpdesk notification templates.  |
|  `tag`  |  `Tag`  |  Represents the tag that triggered the notification.  |
|  `cluster`  |  `Issue`  |  Represents the root issue in duplicate cluster notifications.  |
|  `only_via_duplicate`  |  `boolean`  |  Indicates that a notification was generated in the context of duplicate clustering.  |
|  `init_notification`  |  `boolean`  |  Indicates that the recipient is receiving the first notification in the current thread.  |
|  `last_notification`  |  `boolean`  |  Indicates that the recipient is losing access to the issue or article after this notification, so this is the last notification they can receive for that thread.  |
|  `reason`  |  `Reason`  |  Describes why the recipient received the notification, including saved searches, mentions, tags, reactions, ticket reasons, and duplicate-cluster reasons.  |
|  `project`  |  `Project`  |  Represents the imported project, or the project that failed to import. This variable is used in the "Import status" notification.  |
|  `exception`  |  `Throwable`  |  Represents a Java `Throwable` object.  |
|  `message`  |  `string`  |  Contains the message text in the "Import status" notification.  |
|  `markup`  |  `MarkupDirective`  |  Exposes the markup renderer in templates that provide the markup model.  |
|  `event`  |  `Event`  |  Represents the event adapter in templates that work with a single notification event.  |
|  `commandList`  |  `CommandList`  |  Provides the command list in templates related to command execution.  |
|  `url`  |  `string`  |  Provides a URL value for templates that pass the target location as a top-level variable.  |
|  `subject`  |  `string`  |  Provides the notification subject text when it is exposed as a top-level variable.  |
|  `html_body`  |  `string`  |  Provides the rendered HTML body in templates that work with generated notification content.  |
|  `text_body`  |  `string`  |  Provides the rendered plain-text body in templates that work with generated notification content.  |
|  `integration_configuration`  |  `Configuration`  |  Represents the integration configuration entity in integration-specific templates.  |
|  `integration_context_params`  |  `List`  |  Contains the integration context parameters that are passed to integration-specific templates.  |
|  `threadSubject`  |  `string`  |  Provides the thread subject when the notification channel tracks a conversation thread.  |
|  `channel`  |  `string`  |  Identifies the notification channel for templates that support multiple delivery channels.  |

> **Note:**
> Objects like `Issue`, `Comment`, `Article`, `Change`, `Field`, and `Reason` use notification-specific adapters. Other entities, such as `User`, `Tag`, and `Project`, generally follow the same access pattern as entity objects in workflows.

## Type Reference

This reference lists the members that are explicitly exposed by the current notification template adapters in YouTrack.

### Issue

The `Issue` type combines standard issue data with notification-specific helper members.

* To print the issue ID, use `${issue.id}`.

* To link to the issue, use `<a href="${issue.url}">${issue.id}</a>`.

Older templates may use `${issue.getId()}` or `${Utils.getUrl(issue)}` for the same result.

| Member | Description |
| --- | --- |
| `id` | The issue ID. |
| `isStarred` | Indicates whether the recipient has starred the issue. |
| `isResolved` | Indicates whether the issue is resolved. |
| `attachments` | The attachments that are visible to the recipient. |
| `invisibleAttachmentCount` | The number of attachments that are hidden from the recipient. |
| `comments` | The comments that are visible to the recipient. |
| `tags` | The tags that are visible to the recipient. |
| `linkRoles` | The link roles that are available for the issue. |
| `fields` | The custom fields that are visible to the recipient. |
| `url` | The absolute URL for the issue. |
| `getLinkedIssues(linkRole)` | Returns issues that are linked with the specified role. |
| `get(key)` | Returns a property value by name. This can be used to access standard issue fields like `summary`, `description`, `votes`, `created`, `project`, or `reporter`. |

### Comment

| Member | Description |
| --- | --- |
| `id` | The internal ID of the comment. |
| `author` | The user who wrote the comment. |
| `text` | The comment text. |
| `url` | The absolute URL for the comment. |
| `created` | The creation timestamp. |
| `updated` | The last update timestamp. |
| `attachments` | The attachments that are visible to the recipient. |

### Article

| Member | Description |
| --- | --- |
| `id` | The article ID. |
| `project` | The project that contains the article. |
| `author` | The author of the article. |
| `title` | The article title. |
| `body` | The article body. |
| `url` | The absolute URL for the article. |

### Change

| Member | Description |
| --- | --- |
| `id` | The identifier of the change. |
| `author` | The user who applied the change. |
| `startTimestamp` | The start of the merge interval. |
| `endTimestamp` | The end of the merge interval. |
| `events` | The event adapters that describe the visible changes. |
| `when` | A human-readable representation of the change time. |
| `hasEvent(categoryName)` | Checks whether the change contains an event in the specified category. |
| `isEmpty()` | Checks whether the change contains any visible events. |

### Field

| Member | Description |
| --- | --- |
| `name` | The field name. |
| `value` | The rendered field value. |
| `backgroundColor` | The background color that is associated with the field value. |
| `foregroundColor` | The foreground color that is associated with the field value. |
| `isMultiValue` | Indicates whether the field supports multiple values. |
| `isReadAccessible` | Indicates whether the field is visible to the recipient. |
| `isUsingMarkup` | Indicates whether the field stores markup text. |
| `type` | The field type name. |
| `isVisibleInIssue(issue)` | Checks whether the field is shown for the specified issue. |

### Reason

| Member | Description |
| --- | --- |
| `savedSearchReasons` | The saved search rules that matched the notification. |
| `tagReasons` | The tag-based rules that matched the notification. |
| `mentionReasons` | The mention-based reasons that matched the notification. |
| `clusterReason` | The duplicate cluster reason, when present. |
| `helpdeskReason` | The helpdesk reason, when present. |
| `reactionReasons` | The reaction-based reasons that matched the notification. |
| `ticketReasons` | The helpdesk ticket reasons that matched the notification. |
| `subreasons` | A flattened list of the applicable reasons. |

Each item in the reason collections exposes the following members: `name`, `type`, `issueId`, `underlyingEntityId`, `underlyingEntity`, `mask`, and `debugInfo`.

## Directives

You use FTL tags to call directives. Besides [built-in directives](https://freemarker.apache.org/docs/ref_directives.html) like the `#list` directive, you can define your own directives in Freemarker. For more information, see the [User-Defined directives manual](https://freemarker.apache.org/docs/ref_directive_userDefined.html).

### markup

`markup` processes embedded text using the YouTrack markup renderer for the current issue context.

| Parameter | None |
| Body | Text to process. |

Example:

```HTML
@wikisolidhtml
            <#escape x as x?html>
            ...
            <@markup><#noescape>${comment.text}</#noescape></@markup>
            ...
            </#escape x as x?html>
```

### l10n

`l10n` renders the body without additional parameters. Use this directive for localized template fragments.

| Parameter | None |
| Body | Text to render. |

### diff

`diff` renders an HTML element that highlights changes applied to text. Deleted and added sections of text are marked with different styles.

| Parameters | `oldText`, `newText`, `insStyle`, and `delStyle`. |
| Body | None |

Parameter details:

* `oldText` is the old version of the text.

* `newText` is the new version of the text.

* `insStyle` is the HTML style for inserted text.

* `delStyle` is the HTML style for deleted text.

Example:

```HTML
@diffsolidhtml
            <@diff oldText="Previous text"
            newText="Updated text"
            insStyle="background-color: #E6FFE6;"
            delStyle="background-color: #FFE6E6;"/>
```

### stacktrace

`stacktrace` renders the HTML component that represents the stack trace of a `Throwable`.

| Parameter | `throwable`, an instance of the Java `Throwable` class. |
| Body | None |

Example:

```HTML
@stacktracesolidhtml
            <div><pre><@stacktrace throwable=exception/></pre></div>
```

## Utils

The `Utils` object exposes helper methods that you can call from notification templates when a value is not available directly as an object property, or when you need a formatted URL or presentation helper.

* When the type assigned to a returned value is `list<?>`, you can iterate over the result using the `#list` directive.

* The helper methods in this section are exposed as static methods of the `Utils` object.

|  Method  |  Description  |
| --- | --- |
|  `getAttachmentUrl(attachment) -> string`  |  Returns the URL for the specified attachment resource.  |
|  `getAvatarUrl(user) -> string`  |  Returns the URL for the specified user's avatar.  |
|  `getCommentReplyUrl(comment) -> string`  |  Returns the URL of the issue view with focus on the reply text area for the specified comment.  |
|  `getCommentUrl(comment) -> string`  |  Returns the URL of the issue view with focus on the specified comment.  |
|  `getDuplicate(source) -> Issue`  |  Returns the issue marked as a duplicate of the source issue, or `null` if no such issue exists.  |
|  `getIconSrc(name) -> string`  |  Returns the URL of the built-in icon resource with the specified name.  |
|  `getExplicitTags(issue) -> list<Tag>`  |  Returns the tags that are visible for the notification recipient, excluding the `Star` tag.  |
|  `getInvisibleAttachmentsCount(issue) -> int`  |  Returns the number of issue attachments that are not visible to the notification recipient.  |
|  `getLinkedIssues(source, linkRole) -> list<Issue>`  |  Returns the issues that are linked to the source issue with the specified link role, such as Relates or Duplicate.  |
|  `getLinkRoles(source) -> list<string>`  |  Returns all available link roles for the source issue.  |
|  `getPossessiveName(from, to) -> string`  |  Returns `you` when both users are the same. Otherwise, returns the visible name of the `from` user.  |
|  `getSettingUrlWithMute(user, issue) -> string`  |  Returns an unsubscribe URL for the specified user and issue.  |
|  `getSettingUrl(user) -> string`  |  Returns the URL of the specified user's YouTrack profile with focus on the Notifications tab.  |
|  `getStarSrc(issue) -> string`  |  Returns the URL of the image resource for the Star tag.  |
|  `getTaggedIssuesUrl(tag) -> string`  |  Returns the URL of the Issues list filtered by the specified tag.  |
|  `getTagStyle(tag) -> string`  |  Returns an inline CSS style string for the specified tag.  |
|  `getTrimmedTagName(tag) -> string`  |  Returns the name of the specified tag, limited to the first 25 characters.  |
|  `getUrl(issue) -> string`  |  Returns the URL of the specified issue.  |
|  `getVisibilityPresentation(entity) -> string`  |  Returns a human-readable description of the visibility restrictions for the specified entity.  |
|  `hasLinks(issue) -> boolean`  |  Checks whether the specified issue has any links.  |
|  `hasSameVisibility(first, second) -> boolean`  |  Checks whether the specified entities have the same visibility restrictions.  |
|  `hasVisibilityRestrictions(entity) -> boolean`  |  Checks whether the specified entity has visibility restrictions.  |
|  `inUserTimeZone(time) -> string`  |  Returns the specified time in a human-readable format that is converted to the message recipient's local time zone.  |

