Templates | Vale
For the complete documentation index, see llms.txt. This page is also available as Markdown.

Templates

Learn how to write an output format of your own.

--output takes CLI, line, or JSON, and otherwise the name of a template: a Go template that Vale renders with the run's alerts in place of a built-in format.

vale --output=sarif.tmpl docs/ > vale.sarif

The value is read as a path first. When no file is there, it is looked up by name on the StylesPath, where templates live in config/templates.

The exit code is the same as for any other format: 1 when an alert at the error level was reported, 0 otherwise, and --no-exit turns the first into the second.

The data

A template is executed once, with the whole run:

type Data struct {
    Files       []ProcessedFile // every file that had at least one alert
    LintedTotal int             // every file the run read, alerts or not
}

type ProcessedFile struct {
    Path   string
    Alerts []core.Alert
}

A file with no alerts is left out of Files and counted in LintedTotal, which is how a summary line can say "in 12 files" while ranging over three. Each alert has the fields the JSON output shows: Check, Severity, Message, Description, Link, Match, Line, Span, Action, and Suggestions. Span is a pair of one-based character columns, and both ends are inclusive.

The functions

Every function in Sprig is available, which covers strings, lists, dictionaries, and arithmetic. Vale adds these:

Name
Argument(s)
Description

red

string

The string in red.

yellow

string

The string in yellow.

blue

string

The string in blue.

underline

string

The string underlined.

newTable

bool

A table with no borders that writes to standard output. The argument says whether cell text wraps.

addRow

Table, []string

The table with the row appended. Returns the table, so it chains.

renderTable

Table

Print the table, with a blank line before and after, and empty it for reuse.

jsonEscape

string

The string escaped for use inside a JSON string literal, without the surrounding quotes.

The colors and the underline are terminal escapes, so a template meant to be redirected to a file should leave them out; --no-color disables them for a run.

Examples

Customizing the default output

The following example re-implements Vale’s default output style using a template.

Creating a RDJSONL template

The following example converts Vale’s output to RDJSONL, which you can then pass to Reviewdog to display on pull request. This can be useful when the Vale action is not suitable for your workflow.

Two things are worth knowing when adapting this. Reviewdog reads a range, so giving it the end of the span -- Span is inclusive, and Reviewdog's end is not -- is what underlines the match rather than pointing at its first character. And Reviewdog counts columns in UTF-8 bytes where Vale counts characters, so the two agree only until a line picks up its first multi-byte character; converting between them needs the source line, which a template can't read.

Creating a SARIF template

The following example converts Vale's output to SARIF, the format that GitHub code scanning, GitLab, and Azure DevOps read. Unlike a pull request comment, an alert reported this way persists: it has a history, and someone can dismiss it with a reason.

In a GitHub workflow, hand the file to upload-sarif:

Two details make the conversion straightforward. SARIF measures columns in characters, as Vale's Span does, so the positions carry over unchanged. And SARIF asks for each rule to be described once, which dict and set collect in a pass over the alerts before any output.

Last updated