Skip to content
Vulnotes LogoVulnotes
Syntax

Syntax

Vulnotes templates use the LiquidJS template engine. This page covers the syntax basics you need to write templates.

Live debugger

A live LiquidJS debugger is available in the report preview. It lets you test your template expressions directly against the actual report context (variables, filters, loops) and see the rendered output in real-time.

LiquidJS Debugger

Output

Use double curly braces to output a variable:

liquid
{{ report.title }}
{{ client.name }}
{{ stats.totalVulnerabilities }}

You can chain filters with the pipe | character:

liquid
{{ report.title | uppercase }}
{{ vuln.cvss.score | score }}

Conditionals

if / elsif / else

liquid
{% if stats.criticalCount > 0 %}
    {{ stats.criticalCount }} critical vulnerabilities found.
{% elsif stats.highCount > 0 %}
    {{ stats.highCount }} high vulnerabilities found.
{% else %}
    No critical or high vulnerabilities found.
{% endif %}

Comparison operators

OperatorDescription
==Equal
!=Not equal
>Greater than
<Less than
>=Greater or equal
<=Less or equal

Logical operators

liquid
{% if stats.criticalCount > 0 and stats.highCount > 0 %}
  Both critical and high vulnerabilities were identified.
{% endif %}

{% if stats.criticalCount == 0 or stats.highCount == 0 %}
  No critical or no high vulnerabilities.
{% endif %}

Truthy / falsy checks

liquid
{% if scope.description %}
  {{ scope.description }}
{% endif %}

unless

unless is the opposite of if:

liquid
{% unless stats.totalVulnerabilities == 0 %}
  Vulnerabilities were identified during the assessment.
{% endunless %}

case / when

Inside a loop, use the loop variable:

liquid
{% case vuln.severity %}
  {% when 'Critical' %}
    Immediate action required
  {% when 'High' %}
    Action required
  {% when 'Medium' %}
    Should be addressed
  {% when 'Low' %}
    Consider fixing
  {% else %}
    Informational
{% endcase %}

Loops

for

Loop through arrays like vulnerabilities, scope entries, or contacts:

liquid
{% for vuln in vulnerabilities %}
  {{ vuln.title }}
  Severity: {{ vuln.severity }}
{% endfor %}

Loop variables

Inside a for loop, you have access to:

VariableDescription
forloop.indexCurrent iteration (1-based)
forloop.index0Current iteration (0-based)
forloop.firsttrue on first iteration
forloop.lasttrue on last iteration
forloop.lengthTotal number of items
liquid
{% for vuln in vulnerabilities %}
  {{ forloop.index }}. {{ vuln.title }}
{% endfor %}

Sorting before looping

liquid
{% for vuln in vulnerabilities | sort_by: 'cvss.score' %}
  {{ vuln.title }}: {{ vuln.cvss.score | score }}
{% endfor %}

limit

Restrict the loop to a maximum number of iterations:

liquid
{% for vuln in vulnerabilities limit: 3 %}
  {{ vuln.title }}
{% endfor %}

offset

Skip a number of items before starting the loop:

liquid
{% for vuln in vulnerabilities offset: 1 %}
  {{ vuln.title }}
{% endfor %}

Assign

Create local variables within a template:

liquid
{% assign total = stats.criticalCount | plus: stats.highCount %}
{{ total }} vulnerabilities rated Critical or High.
liquid
{% assign has_critical = false %}
{% if stats.criticalCount > 0 %}
  {% assign has_critical = true %}
{% endif %}

Page breaks

Insert a page break in the PDF output:

liquid
{% pagebreak %}