> For the complete documentation index, see [llms.txt](https://support.attackforge.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://support.attackforge.com/app/modules/reporting/template-filters.md).

# Template - Filters

## Overview

Template filters change a tag's data before it appears in your report. Use them to sort and select findings, format dates, tidy up text, round numbers, resize images and split lists into columns.

Help, examples and tips are also on the [ReportGen GitHub support site](https://github.com/AttackForge/ReportGen).

<figure><img src="https://372186556-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M8s1QY2Q6YTHB4a6DMu%2Fuploads%2FUsAzUW7ktz9lTWDe1Ulv%2Ftemplate-filters-at-a-glance.svg?alt=media&amp;token=7ff3b3b5-cfbe-497d-b46d-e0431c375090" alt=""><figcaption></figcaption></figure>

## How to write a filter

Add a pipe (`|`) after the tag name, then the filter and its parameters.

| Form                     | Use it to                                                                                | Example                                                |
| ------------------------ | ---------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| `{tag \| filter}`        | Print a value after the filter changes it                                                | `{title \| toUpperCase}`                               |
| `{#tag \| filter}...{/}` | Loop over the items the filter returns, or show what's inside only if the filter is true | `{#vulnerabilities \| sort:["title:asc"]}{title}{/}`   |
| `{^tag \| filter}...{/}` | Show what's inside only if the filter is false or returns nothing                        | `{^tags \| hasAny:['CVE','cve']}No CVEs Identified{/}` |

**Chain filters** by adding more pipes. They run from left to right. For example, `{asset | replace:["https://",""] | replace:["http://",""] | search:["/"]}`.

## All filters

| Group                     | Filter                                                    | What it does                                                                               |
| ------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| **Sort and select**       | `sort`                                                    | Sorts a list by one or more keys                                                           |
|                           | `filter`                                                  | Keeps list items that match a condition                                                    |
|                           | `filterBy`                                                | Keeps vulnerabilities whose affected assets match properties, custom tags or custom fields |
|                           | `find`                                                    | Returns the first item where a field matches a value                                       |
|                           | `findVuln`                                                | Finds a stored vulnerability by title and priority                                         |
|                           | `index`                                                   | Returns the item at a position in a list                                                   |
|                           | `unique`                                                  | Prints a value only the first time it appears                                              |
|                           | `count`                                                   | Counts how many times it runs                                                              |
| **Check values**          | `hasAny`, `hasAll`                                        | Checks if a tag has any, or all, of a list of values                                       |
|                           | `includes`, `excludes`                                    | Continues only if a tag does, or doesn't, contain a value                                  |
|                           | `isArray`, `isBoolean`, `isInteger`, `isString`           | Checks a value's type                                                                      |
| **Text**                  | `replace`, `replaceRegExp`                                | Replaces text, or text matching a regular expression                                       |
|                           | `split`, `splitRegExp`                                    | Splits text into a list                                                                    |
|                           | `search`                                                  | Returns text from the first match onwards                                                  |
|                           | `substring`                                               | Returns part of the text                                                                   |
|                           | `trim`                                                    | Removes spaces before and after                                                            |
|                           | `capitalize`, `toTitleCase`, `toUpperCase`, `toLowerCase` | Changes the case                                                                           |
| **Numbers**               | `toFloat`, `integer`                                      | Converts to a decimal or a whole number                                                    |
|                           | `round`, `roundUp`, `roundDown`                           | Rounds a number                                                                            |
|                           | `increment`, `multiply`                                   | Adds to, or multiplies, a number                                                           |
| **Dates**                 | `dateFormat`                                              | Formats a date                                                                             |
|                           | `dateAdd`, `dateSubtract`                                 | Adds or subtracts time                                                                     |
|                           | `dateDiff`                                                | Gets the time between two dates                                                            |
| **Variables and storage** | `declare`, `assign`                                       | Saves a value to a variable                                                                |
|                           | `store`                                                   | Saves data to a custom tag                                                                 |
|                           | `drop`                                                    | Hides a value from the report                                                              |
| **Lists and images**      | `array_chunk`                                             | Splits a list into groups, such as columns                                                 |
|                           | `resize`                                                  | Resizes images                                                                             |

## Why it matters

* **One template, many reports.** Filters pick and shape the data for each audience, so you don't need a separate template for every variation.
* **Cleaner reports.** Dates, case, numbers and URLs come out consistently, without manual editing.
* **Less work after generating.** Sorting, grouping and counting happen in the template, not in Word.

## Who uses it

| Who                                  | To                                                            |
| ------------------------------------ | ------------------------------------------------------------- |
| **Report template authors**          | Sort, select and format data in templates                     |
| **Consultancies and MSSPs**          | Produce client-ready reports in each client's preferred style |
| **Developers and integration teams** | Build advanced templates for automated reports                |

## Sort and select filters

### sort

Sorts a tag's data by one or more keys, in ascending or descending order.

```
{tag | sort:["key:<asc/desc>"]}
```

| Parameter | Description                            |
| --------- | -------------------------------------- |
| **key**   | A JSON object key available in scope.  |
| **asc**   | Sorts data by key in ascending order.  |
| **desc**  | Sorts data by key in descending order. |

**Example 1 — single-key sort (vulnerabilities):**

```
{#vulnerabilities | sort:["cvssv3_base_score:asc"]}
{title} - {cvssv3_base_score}
{/}
```

**Example 1 — single-key sort (affected assets):**

```
{#affected_assets | sort:["cvssv3_base_score:asc"]}
{name} - {cvssv3_base_score}
{/}
```

**Example 2 — multi-key sort (vulnerabilities):**

```
{#vulnerabilities | sort:["cvssv3_base_score:asc","title:desc"]}
{title} - {cvssv3_base_score}
{/}
```

**Example 2 — multi-key sort (affected assets):**

```
{#affected_assets | sort:["cvssv3_base_score:asc","name:asc"]}
{name} - {cvssv3_base_score}
{/}
```

### filter

Keeps only the list items that match a condition.

```
{#vulnerabilities | filter:'condition'}
```

The condition supports these operators:

| Operator       | Meaning                       |
| -------------- | ----------------------------- |
| `NOT` or `!`   | Negates an expression         |
| `AND` or `&&`  | Both expressions must be true |
| `OR` or `\|\|` | Either expression can be true |
| `==`           | Equivalency                   |
| `===`          | Equality                      |
| `!==`          | Not equivalency               |
| `>`            | Greater than                  |
| `<`            | Less than                     |
| `>=`           | Greater than or equal to      |
| `<=`           | Less than or equal to         |
| `( )`          | Groups statements together    |

**Example 1** — vulnerabilities that are Critical AND easily exploitable:

```
{#vulnerabilities | filter:’easily_exploitable === true AND priority === “Critical”’}
{title}
{/}
```

**Example 2** — affected assets by remediation status AND the parent vulnerability's priority:

```
{#vulnerabilities}
{#affected_assets | filter:’remediation_status === "Open" AND parent.priority === “Critical”’}
{title}
{/}{/}
```

**Example 3** — filter on custom tags:

```
{#vulnerabilities}
{#affected_assets} 
{#assetCustomTags | filter:’owasp_top_10 === "yes"’}
{title}
{/}{/}{/}
```

**Example 4** — filter on custom fields:

```
{#vulnerabilities}
{#affected_assets} 
{#assetCustomFields | filter:’owasp_top_10 === "yes"’}
{title}
{/}{/}{/}
```

**Example 5** — combine with functions to push matches into a new list, using the `parent` object:

```
{$declare[OWASP_Top_10_Vulns][[]]}
{#vulnerabilities}
{#affected_assets} 
{#assetCustomTags | filter:’owasp_top_10 === "yes"’}
{$push[OWASP_Top_10_Vulns][“%(parent.parent)”]}
{/}{/}{/}
...
{#$value[OWASP_Top_10_Vulns]}
{title}
{/}
```

**Example 6** — the same, using scope:

```
{$declare[OWASP_Top_10_Vulns][[]]}
{#vulnerabilities}
{#affected_assets} 
{#assetCustomTags | filter:’owasp_top_10 === "yes"’}
{$push[OWASP_Top_10_Vulns][“%(../../)”]}
{/}{/}{/}
...
{#$value[OWASP_Top_10_Vulns]}
{title}
{/}
```

### filterBy

Keeps the vulnerabilities whose affected assets match given properties, custom tags or custom fields. It can also count the matching vulnerabilities.

```
{#vulnerabilities | filterBy:'Condition':['key:value']:'AND'}
```

| Parameter     | Description                                                   |
| ------------- | ------------------------------------------------------------- |
| **Condition** | What to match on. See the supported conditions below.         |
| **key:value** | An array of one or more key:value conditions.                 |
| **AND / OR**  | Optional. How to combine several conditions. Defaults to AND. |

Supported conditions:

* `filterBy:'AffectedAssetProperties'`
* `filterBy:'AffectedAssetCustomTags'`
* `filterBy:'AffectedAssetCustomFields'`
* `filterBy:'AffectedAssetCustomTags-CountVulns'`
* `filterBy:'AffectedAssetCustomFields-CountVulns'`

> **Important:** CustomFields are used in the exact same way as CustomTags within this filter.

**filterBy:'AffectedAssetProperties'**

Vulnerabilities with a closed affected asset:

```
{#vulnerabilities | filterBy:'AffectedAssetProperties':['status:Closed']}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
```

Vulnerabilities with an affected asset that's Open OR in Retest:

```
{#vulnerabilities | filterBy:’AffectedAssetProperties’:[‘status:Open’,’status:Retest’]:’OR’}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
```

To see the affected asset properties you can filter on, use `$help`:

```
{#vulnerabilities}
{#affected_assets}
{$help["%()"]}
{/}{/}
```

**filterBy:'AffectedAssetCustomTags'**

Single condition:

```
{#vulnerabilities | filterBy:'AffectedAssetCustomTags':['Source:External']}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
```

AND operator:

```
{#criticalVulnerabilities | filterBy:'AffectedAssetCustomTags':['Source:External','OWASPTop10:True']:'AND'}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
```

OR operator:

```
{#criticalVulnerabilities | filterBy:'AffectedAssetCustomTags':['Source:External','OWASPTop10:True']:'OR'}
{priority} - {title}
{#affected_assets}
{asset}
{/}{/}
```

**filterBy:'AffectedAssetCustomTags-CountVulns'**

Prints the number of matching vulnerabilities, instead of looping over them.

Single condition:

```
{vulnerabilities | filterBy:'AffectedAssetCustomTags-CountVulns':['Source:External']}
```

AND operator.

```
{criticalVulnerabilities | filterBy:'AffectedAssetCustomTags':['Source:External','OWASPTop10:True']:'AND'}
```

OR operator.

```
{criticalVulnerabilities | filterBy:'AffectedAssetCustomTags':['Source:External','OWASPTop10:True']:'OR'}
```

**Use scope or variables in filterBy**

This example groups vulnerabilities by testing phase, using a project custom field and a variable in the condition:

```
{$declare[TestingPhaseVulns][<Dictionary>]}
{#projectCustomFields}
{#testing_phases}
{$declare[CurrentPhase][“%(./)”]}
{$declare[TestingPhaseVulns[“$(CurrentPhase)”]][[]]}
{#vulnerabilities | filterBy:“AffectedAssetCustomFields”:[“testing_phase:$(CurrentPhase)”]}
{$push[TestingPhaseVulns[“$(CurrentPhase)”]][“%(./)”]}
{/}{/}{/}
{#$keys[TestingPhaseVulns]}
Vulnerabilities for Testing Phase: {this[0]}
{#this[1]}
Vulnerability Title: {title}
{/}{/}
```

### find

Returns the first object in a list where a field matches a value.

```
{#vulnerabilities | find:"title":"Missing X-XSS-Protection Header"}
{title}
{/}
```

| Parameter | Description                        |
| --------- | ---------------------------------- |
| **field** | The key to match, such as `title`. |
| **value** | The value to match.                |

### findVuln

Finds a vulnerability in the project's full list by its title and priority. Use it with `store`, which saves the full list first.

| Parameter      | Description                                                   |
| -------------- | ------------------------------------------------------------- |
| **stored tag** | The name of the tag saved with `store`, such as `'allVulns'`. |
| **title**      | The vulnerability title, such as `this.vulnerability`.        |
| **priority**   | The vulnerability priority, such as `this.priority`.          |

**Example** — print full vulnerability details for each asset in the asset-to-vulnerability mapping:

```
{#vulnerabilities}{#title | store:’allVulns’:this}{/}{/}
{#assetVulnerabilityMapping}
{asset}
{#vulnerabilities}
{priority} - {status} - {vulnerability}
{#vulnerabilities | findVuln:’allVulns’:this.vulnerability:this.priority}
{description}
{attack_scenario}
{remediation_recommendation}

{/}{/}{/}
```

### index

Returns the item at a given position in a list. The first item is 0.

**Example** — the first vulnerability:

```
{#vulnerabilities | index:["0"]}
{title}
{/}
```

### unique

Prints a value only the first time it appears in the report. Use it to avoid duplicates when you loop over affected assets.

| Parameter | Description                                                    |
| --------- | -------------------------------------------------------------- |
| **key**   | The value being checked, such as `{title}`.                    |
| **value** | A name for the report section, such as `'InternalVulnsTable'`. |

**Example** — each Critical vulnerability on an internal asset, once:

```
{#vulnerabilities}
{#priority == “Critical”}
{#affected_assets}
{#assetCustomTags}
{#Source == “Internal”}
{#title | unique:'InternalVulnsTable'}
{title}
{/}{/}{/}{/}{/}{/}
```

### count

Sets a counter that goes up each time the filter runs. The result is saved in a tag named `$count` plus the counter name. Chain it after `unique` to count only unique values.

| Parameter | Description                                               |
| --------- | --------------------------------------------------------- |
| **key**   | The value being counted, such as `{title}`.               |
| **value** | The counter name, such as `'InternalVulnsTableCritical'`. |

**Example:**

```
{#vulnerabilities}
{#priority == “Critical”}
{#affected_assets}
{#assetCustomTags}
{#Source == “Internal”}
{#title | unique:'InternalVulnsTable' | count:'InternalVulnsTableCritical'}
{title}
{/}{/}{/}{/}{/}{/}
{#$countInternalVulnsTableCritical}
{$countInternalVulnsTableCritical}
{/}
```

## Filters that check values

### hasAny

Returns `true` if at least one of the values exists in a tag, or `false` if none do.

```
hasAny:['SQL','xss']
```

| Parameter                   | Description                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| **Values to search**        | Required. A list of strings, such as `['SQL','xss']`.                                       |
| **Case-insensitive search** | Optional. `true` or `false`. Defaults to `false`. For example, `hasAny:['SQL','xss']:true`. |

**Example** — list each asset's associated CVEs, or say there are none:

```
{#vulnerabilities}
Vulnerability: {title}
{#affected_assets}
Affected Asset: {asset}
{#tags | hasAny:['CVE','cve']}Associated CVEs
{#tags}{#this | includes:['CVE','cve']}{.}
{/}{/}{/}
{^tags | hasAny:['CVE','cve']}No CVEs Identified{/}
{/}{/}
```

### hasAll

Returns `true` only if all of the values exist in a tag.

```
hasAll:['OWASP Top 10','CWE Top 25']
```

| Parameter                   | Description                                           |
| --------------------------- | ----------------------------------------------------- |
| **Values to search**        | Required. A list of strings, such as `['SQL','xss']`. |
| **Case-insensitive search** | Optional. `true` or `false`. Defaults to `false`.     |

**Example:**

```
{#vulnerabilities}
Vulnerability: {title}
{#affected_assets}
Affected Asset: {asset}
{#tags | hasAll:['OWASP Top 10','CWE Top 25']}OWASP Top 10 & CWE Top 25{/}
{^tags | hasAll:['OWASP Top 10','CWE Top 25']}Not OWASP Top 10 & CWE Top 25{/}
{/}{/}
```

### includes

Continues only if a tag contains one of the values. Partial matches count, so "Blind SQL Injection" matches "SQL Injection".

```
{#title | includes:['SQL Injection','Cross Site Scripting']}
```

| Parameter  | Description                                                |
| ---------- | ---------------------------------------------------------- |
| **values** | A value or a list of values. Supports scope and variables. |

**Example 1** — match on title:

```
{#vulnerabilities}
{#title | includes:['SQL Injection','Cross Site Scripting']}
{priority} - {title}
{/}{/}
```

**Example 2** — use on a list of strings (show only the CVE tags):

```
{#vulnerabilities}
{title}
{#tags}{#this | includes:['CVE','cve']}CVE: {.}
{/}{/}
{/}
```

**Example 3 — scope:**

```
{#projectCustomFields}
{#customer_name}
{#projectGroups}
{#name | includes:[“%(../customer_name)”]}
Customer {customer_name} has access to this project.
{/}{/}{/}{/}
```

**Example 4 — variables:**

```
{$declare[CustomerName][“”]}
{#projectCustomFields}
{#customer_name}
{$assign[CustomerName][“%(customer_name)”]}
{/}{/}

{#projectGroups}
{#name | includes:[“$(CustomerName)”]}
Customer {$value[CustomerName]} has access to this project.
{/}{/}
```

See [scope](https://support.attackforge.com/app/modules/reporting/template-functions) and [variables](https://support.attackforge.com/app/modules/reporting/template-functions) on Template Functions.

### excludes

Continues only if a tag doesn't contain any of the values, including partial matches.

```
{#title | excludes:['SQL Injection','Cross Site Scripting']}
```

| Parameter  | Description                                                |
| ---------- | ---------------------------------------------------------- |
| **values** | A value or a list of values. Supports scope and variables. |

**Example:**

```
{#vulnerabilities}
{#title | excludes:['SQL Injection','Cross Site Scripting']}
{priority} - {title}
{/}{/}
```

### isArray, isBoolean, isInteger and isString

Check whether a value is a list (array), a boolean, an integer or a string. They take no parameters.

```
{tags | isArray}
```

```
{easily_exploitable | isBoolean}
```

```
{totalVulns | isInteger}
```

```
{projectName | isString}
```

## Text filters

### replace

Replaces text in a tag's data.

```
{asset | replace:["https://",""]}
```

| Parameter       | Description                                                      |
| --------------- | ---------------------------------------------------------------- |
| **search**      | The text to find, such as `https://`.                            |
| **replacement** | The text to put in its place. An empty string removes the match. |

**Example** — remove `https://` from each affected asset:

```
{#vulnerabilities}
{#affected_assets}
{asset | replace:[“https://”,“”]}
{/}{/}
```

### replaceRegExp

Replaces text that matches a regular expression.

```
{asset | replaceRegExp:["[?].*",""]}
```

| Parameter       | Description                                                                     |
| --------------- | ------------------------------------------------------------------------------- |
| **pattern**     | The regular expression to match. `[?].*` matches a `?` and everything after it. |
| **replacement** | The text to put in its place. An empty string removes the match.                |

**Example** — remove a query string, such as `?query=1`, from each affected asset:

```
{#vulnerabilities}
{#affected_assets}
{asset | replaceRegExp:[“[?].*”,“”]}
{/}{/}
```

### split

Splits text on a separator and returns a list.

```
{#this | split:[":"]}
```

| Parameter     | Description                          |
| ------------- | ------------------------------------ |
| **separator** | The text to split on, such as `":"`. |

**Example** — for tags written as `key:value`, show only the right-hand side:

```
{#vulnerabilities}
{#tags}
{$declare[tagSplitCounter][0]}
{#this | split:[“:”]}
{#$greaterThan[tagSplitCounter][0]}{.}{/}
{#$equals[tagSplitCounter][0]}{$increment[tagSplitCounter][1]}{/}
{/}{/}{/}
```

### splitRegExp

Splits text on a regular expression and returns a list.

```
{#description | splitRegExp:["\n\n"]}
```

| Parameter     | Description                                                                                    |
| ------------- | ---------------------------------------------------------------------------------------------- |
| **separator** | A regular expression to split on. `"\n\n"` splits on a blank line, which separates paragraphs. |

**Example** — show only the first paragraph of each vulnerability's description:

```
{#vulnerabilities}
{title}
{$declare[SplitDecriptionOnParagraph][1]}
{#description | splitRegExp:[“\n\n“]}
{#$lessThanOrEqual[SplitDecriptionOnParagraph][1]}{.}{/}{$increment[SplitDecriptionOnParagraph][1]}
{/}{/}
```

### search

Finds the first match of a value and returns the text from that point onwards.

```
{asset | search:["/"]}
```

| Parameter | Description                            |
| --------- | -------------------------------------- |
| **value** | The text to search for, such as `"/"`. |

**Example** — show only the path of each URL, by chaining `replace` and `search`:

```
{#vulnerabilities}
{#affected_assets}
{asset | replace:["https://",""] | replace:["http://",""] | search:["/"]}
{/}{/}
```

### substring

Returns part of a string. If the substring can't be worked out, the original string is returned.

```
{projectName | substring:[3,12]}
```

| Parameter | Description                                                                                          |
| --------- | ---------------------------------------------------------------------------------------------------- |
| **start** | Required. The position to start from. The first character is 0.                                      |
| **end**   | Optional. The position to stop at. If you leave it out, the substring runs to the end of the string. |

**Example** — basic calls, then a project name cut to 12 characters with an ellipsis:

```
{projectName | substring:[3]}
{projectName | substring:[3,12]}
{projectName | substring:[0,12]}
{!! If project name is more than 12 characters long, return the first 12 characters then add ... after the end of the substring }
{#projectName.length > 12}
{projectName | substring:[0,12]}...
{/}
```

### trim

Removes spaces before and after a tag's value.

```
{title | trim}
```

### capitalize, toTitleCase, toUpperCase and toLowerCase

Change the case of a tag's value. They take no parameters.

| Filter        | What it does                                                  | Example                  |
| ------------- | ------------------------------------------------------------- | ------------------------ |
| `capitalize`  | First character uppercase, the rest lowercase                 | `{title \| capitalize}`  |
| `toTitleCase` | Each word starts with an uppercase letter, the rest lowercase | `{title \| toTitleCase}` |
| `toUpperCase` | All uppercase                                                 | `{title \| toUpperCase}` |
| `toLowerCase` | All lowercase                                                 | `{title \| toLowerCase}` |

## Number filters

### toFloat

Converts a number to a decimal (floating-point) number. If the conversion fails, it returns 0.0.

```
{cvssv3_base_score | toFloat:'2'}
```

| Parameter          | Description                                                                |
| ------------------ | -------------------------------------------------------------------------- |
| **decimal places** | Optional. How many decimal places to keep, as a string. Defaults to `'2'`. |

### integer

Converts a number to a whole number (integer). If the conversion fails, it returns 0.

```
{cvssv3_base_score | integer}
```

### round, roundUp and roundDown

Round a number to the nearest whole number, up, or down. They take no parameters.

```
{cvssv3_base_score | round}
```

```
{cvssv3_base_score | roundUp}
```

```
{cvssv3_base_score | roundDown}
```

### increment

Adds 1 to a number, or adds the number you give.

| Parameter  | Description                                  |
| ---------- | -------------------------------------------- |
| **amount** | Optional. The integer to add. Defaults to 1. |

```
{totalVulns | increment}
{totalVulns | increment:25}
```

### multiply

Multiplies a number by an integer.

| Parameter      | Description                 |
| -------------- | --------------------------- |
| **multiplier** | The integer to multiply by. |

```
{totalVulns | multiply:5}
```

## Date filters

### dateFormat

Formats a date using a named format or a mask. You can also give a timezone.

```
{tag | dateFormat:["namedFormat/mask"]}
```

```
{timestamp | dateFormat:["fullDate"]}
```

With a timezone:

```
{tag | dateFormat:"namedFormat/mask":"timezone"}
```

```
{timestamp | dateFormat:"isoDateTime":"America/Chicago"}
```

| Parameter              | Description                                                                                                                                  |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **namedFormat / mask** | One of the named formats, or a mask built from the options below.                                                                            |
| **timezone**           | Optional. A canonical timezone name. See the [list of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). |

**Named formats**

| Name              | Mask                         | Example                  |
| ----------------- | ---------------------------- | ------------------------ |
| `default`         | ddd mmm dd yyyy HH:MM:ss     | Sat Jun 09 2007 17:46:21 |
| `shortDate`       | m/d/yy                       | 6/9/07                   |
| `paddedShortDate` | mm/dd/yyyy                   | 06/09/2007               |
| `mediumDate`      | mmm d, yyyy                  | Jun 9, 2007              |
| `longDate`        | mmmm d, yyyy                 | June 9, 2007             |
| `fullDate`        | dddd, mmmm d, yyyy           | Saturday, June 9, 2007   |
| `shortTime`       | h:MM TT                      | 5:46 PM                  |
| `mediumTime`      | h:MM:ss TT                   | 5:46:21 PM               |
| `longTime`        | h:MM:ss TT Z                 | 5:46:21 PM EST           |
| `isoDate`         | yyyy-mm-dd                   | 2007-06-09               |
| `isoTime`         | HH:MM:ss                     | 17:46:21                 |
| `isoDateTime`     | yyyy-mm-dd'T'HH:MM:sso       | 2007-06-09T17:46:21+0700 |
| `isoUtcDateTime`  | UTC:yyyy-mm-dd'T'HH:MM:ss'Z' | 2007-06-09T22:46:21Z     |

**Mask options**

| Mask             | Description                                                                                                                                                   |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `d`              | Day of the month as digits; no leading zero for single-digit days.                                                                                            |
| `dd`             | Day of the month as digits; leading zero for single-digit days.                                                                                               |
| `ddd`            | Day of the week as a three-letter abbreviation.                                                                                                               |
| `DDD`            | "Ysd", "Tdy" or "Tmw" if date lies within these three days. Else fall back to ddd.                                                                            |
| `dddd`           | Day of the week as its full name.                                                                                                                             |
| `DDDD`           | "Yesterday", "Today" or "Tomorrow" if date lies within these three days. Else fall back to dddd.                                                              |
| `m`              | Month as digits; no leading zero for single-digit months.                                                                                                     |
| `mm`             | Month as digits; leading zero for single-digit months.                                                                                                        |
| `mmm`            | Month as a three-letter abbreviation.                                                                                                                         |
| `mmmm`           | Month as its full name.                                                                                                                                       |
| `yy`             | Year as last two digits; leading zero for years less than 10.                                                                                                 |
| `yyyy`           | Year represented by four digits.                                                                                                                              |
| `h`              | Hours; no leading zero for single-digit hours (12-hour clock).                                                                                                |
| `hh`             | Hours; leading zero for single-digit hours (12-hour clock).                                                                                                   |
| `H`              | Hours; no leading zero for single-digit hours (24-hour clock).                                                                                                |
| `HH`             | Hours; leading zero for single-digit hours (24-hour clock).                                                                                                   |
| `M`              | Minutes; no leading zero for single-digit minutes.                                                                                                            |
| `MM`             | Minutes; leading zero for single-digit minutes.                                                                                                               |
| `N`              | ISO 8601 numeric representation of the day of the week.                                                                                                       |
| `o`              | GMT/UTC timezone offset, e.g. -0500 or +0230.                                                                                                                 |
| `p`              | GMT/UTC timezone offset, e.g. -05:00 or +02:30.                                                                                                               |
| `s`              | Seconds; no leading zero for single-digit seconds.                                                                                                            |
| `ss`             | Seconds; leading zero for single-digit seconds.                                                                                                               |
| `S`              | The date's ordinal suffix (st, nd, rd, or th). Works well with `d`.                                                                                           |
| `l`              | Milliseconds; gives 3 digits.                                                                                                                                 |
| `L`              | Milliseconds; gives 2 digits.                                                                                                                                 |
| `t`              | Lowercase, single-character time marker string: a or p.                                                                                                       |
| `tt`             | Lowercase, two-character time marker string: am or pm.                                                                                                        |
| `T`              | Uppercase, single-character time marker string: A or P.                                                                                                       |
| `TT`             | Uppercase, two-character time marker string: AM or PM.                                                                                                        |
| `W`              | ISO 8601 week number of the year, e.g. 4, 42                                                                                                                  |
| `WW`             | ISO 8601 week number of the year, leading zero for single-digit, e.g. 04, 42                                                                                  |
| `Z`              | US timezone abbreviation, e.g. EST or MDT. For non-US timezones, the GMT/UTC offset is returned, e.g. GMT-0500                                                |
| `'...'`, `"..."` | Literal character sequence. Surrounding quotes are removed.                                                                                                   |
| `UTC`            | Must be the first four characters of the mask. Converts the date from local time to UTC/GMT/Zulu time before applying the mask. The "UTC:" prefix is removed. |

### dateAdd

Adds time to a date.

| Parameter           | Description                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **amount and unit** | A quoted number and unit: milliseconds, seconds, minutes, hours, days, weeks, months or years. Can also be a variable. |

```
{timestamp | dateAdd:"10 milliseconds"}
{timestamp | dateAdd:"10 seconds"}
{timestamp | dateAdd:"10 minutes"}
{timestamp | dateAdd:"10 hours"}
{timestamp | dateAdd:"10 days"}
{timestamp | dateAdd:"10 weeks"}
{timestamp | dateAdd:"10 months"}
{timestamp | dateAdd:"10 years"}
{timestamp | dateAdd:"$(someDateVariable)"}
```

### dateSubtract

Subtracts time from a date.

| Parameter           | Description                                                                                                            |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| **amount and unit** | A quoted number and unit: milliseconds, seconds, minutes, hours, days, weeks, months or years. Can also be a variable. |

```
{timestamp | dateSubtract:"10 milliseconds"}
{timestamp | dateSubtract:"10 seconds"}
{timestamp | dateSubtract:"10 minutes"}
{timestamp | dateSubtract:"10 hours"}
{timestamp | dateSubtract:"10 days"}
{timestamp | dateSubtract:"10 weeks"}
{timestamp | dateSubtract:"10 months"}
{timestamp | dateSubtract:"10 years"}
{timestamp | dateSubtract:"$(someDateVariable)"}
```

### dateDiff

Gets the time between two dates. The result is in milliseconds unless you give a unit.

| Parameter | Description                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------- |
| **date**  | The date to compare against, in quotes. Can also be scope or a variable.                                 |
| **unit**  | Optional. Milliseconds, seconds, minutes, hours, days, weeks, months or years. Defaults to milliseconds. |

```
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z"}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":milliseconds}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":seconds}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":minutes}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":hours}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":days}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":weeks}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":months}
{timestamp | dateDiff:"2026-02-27T04:28:47.515Z":years}
{timestamp | dateDiff:"%(data.project.created)":days}
{timestamp | dateDiff:"$(someDateVariable)":days}
```

## Variable and storage filters

### declare

Saves a value to a new variable. You can then use the variable with [template functions](https://support.attackforge.com/app/modules/reporting/template-functions).

```
{value | declare:"variableName"}
```

| Parameter        | Description                   |
| ---------------- | ----------------------------- |
| **variableName** | The name of the new variable. |

**Example** — a report valid-to date three months from now:

```
{timestamp | dateAdd:"3 months" | declare:"reportValidToDate"}
{$value[reportValidToDate]}
```

### assign

Saves a new value to an existing variable. You can then use the variable with [template functions](https://support.attackforge.com/app/modules/reporting/template-functions).

```
{value | assign:"variableName"}
```

| Parameter        | Description               |
| ---------------- | ------------------------- |
| **variableName** | The name of the variable. |

**Example:**

```
{totalVulns | multiply:100 | assign:"totalVulnsMultiplied" | drop}
```

### drop

Stops a value appearing in the report. Use it at the end of a chain, when you only want to save the value.

```
{totalVulns | multiply:100 | assign:"totalVulnsMultiplied" | drop}
```

### store

Saves data to a custom tag that you name. You can then use the tag, with its data, anywhere later in the template as `$stored` plus the tag name.

```
{#title | store:'TagName':this}
```

| Parameter           | Description                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------------------- |
| **tag name**        | The name of the custom tag to create, such as `'AllVulns'`.                                                   |
| **value**           | What to store, such as `this` (the current vulnerability).                                                    |
| **list**            | Optional. A list to check, such as `'affected_assets'`.                                                       |
| **custom tag list** | Optional. The custom tag list to check, such as `'assetCustomTags'`.                                          |
| **key:value pairs** | Optional. An array of key:value pairs to match, such as `['Source:Web']`. Several pairs are combined with OR. |

**Example 1** — store all vulnerabilities in a tag called AllVulns:

```
{#vulnerabilities}{#title | store:’AllVulns’:this}{/}{/}
{#$storedAllVulns}
{priority} {title}
{/}
```

**Example 2** — store all Critical web application vulnerabilities on the project:

```
{#vulnerabilities}
{#priority == “Critical”}
{#affected_assets}
{#assetCustomTags}
{#Source == “Web”}
{#title | store:’CriticalWebVulns’:this:’affected_assets’:’assetCustomTags’:[‘Source:Web’]}

{/}{/}{/}{/}{/}{/}
{#$storedCriticalWebVulns}
{priority} {title}
{/}
```

## List and image filters

### array\_chunk

Splits a list into groups of a given size. Use it to show data in columns. Each group is available as `chunk[index]`.

```
array_chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
 
array_chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]

{#tag | array_chunk:<size>}{chunk[0]}{chunk[1]}{chunk[...]}{/}
```

| Parameter | Description                                                                                        |
| --------- | -------------------------------------------------------------------------------------------------- |
| **size**  | How many items in each group. If the list doesn't divide evenly, the last group holds what's left. |

**Example 1** — affected assets in three columns:

*Images 2 and 3: the template, and the result (see the appendix).*

**Example 2** — vulnerability titles in two columns:

*Images 4 and 5: the template, and the result (see the appendix).*

### resize

Resizes images to a fixed width. Images are scaled up or down, and the height changes to keep the same shape.

```
{@proof_of_concept_styled | resize:["300"]}
```

| Parameter | Description                                        |
| --------- | -------------------------------------------------- |
| **width** | The width in pixels, as a string, such as `"300"`. |

**Example** — resize images in Steps to Reproduce (Proof of Concept) to 300 pixels wide:

```
{#vulnerabilities}
{#affected_assets}
{@proof_of_concept_styled | resize:[“300”]}
{/}{/}
```

## Tips

* **Check your data first.** Use `$help` to see the keys you can sort, filter and format on.
* **Chain filters** instead of nesting tags. For example, `replace` then `search` to show only a URL's path.
* **Use `{^tag | filter}` for an "else".** Pair it with `{#tag | filter}` to show a message when nothing matches, such as "No CVEs Identified".
* **Use `unique` and `count` together** to list and count findings without duplicates.
* **Save values for later** with `declare` or `assign`, and add `drop` so they don't print.
* **Format every date the same way.** Pick one `dateFormat` and use it throughout the template.
* **Use straight quotes (") in Word.** Turn off Word's smart quotes when writing tags.

## FAQ

**What's the difference between filters and functions?** Filters change one tag's data, and are added with a pipe (`|`). Functions add logic, such as variables, counting and loops, and start with `$`. You can use them together.

**Can I use more than one filter on a tag?** Yes. Chain them with pipes. They run from left to right.

**What's the difference between `filter` and `filterBy`?** `filter` keeps items in any list that match a condition you write. `filterBy` keeps vulnerabilities based on their affected assets' properties, custom tags or custom fields.

**What's the difference between `includes` and `hasAny`?** `includes` continues if a tag contains a value, including partial matches. `hasAny` returns true or false for whether a tag has any of a list of values.

**How do I format dates in my timezone?** Add a timezone to `dateFormat`, such as `{timestamp | dateFormat:"isoDateTime":"Australia/Melbourne"}` (example).

**How do I show findings in columns?** Use `array_chunk`.

**How do I make proof-of-concept images fit the page?** Use `resize` with a width in pixels.

**Can I use variables in filters?** Yes. Many filters, including `includes`, `excludes`, `filterBy` and the date filters, support scope and variables.

## Related pages

* [Reporting overview](https://support.attackforge.com/app/modules/reporting/overview)
* [Template options](https://support.attackforge.com/app/modules/reporting/template-options)
* [Template functions](https://support.attackforge.com/app/modules/reporting/template-functions)
* [ReportGen on GitHub](https://github.com/AttackForge/ReportGen)
* [ReportGen issue #18: using $help](https://github.com/AttackForge/ReportGen/issues/18)
* [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://support.attackforge.com/app/modules/reporting/template-filters.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
