Check is a Go library for statically type-checking text/template and html/template. It catches template/type mismatches early, making refactoring safer when changing types or templates.
If all your ExecuteTemplate calls use a string literal for the template name and a static type for the data argument, you can use the CLI directly:
go get -tool github.com/typelate/check/cmd/check-templates
go tool check-templates ./...Flags:
-v— list each call with position, template name, and data type-definitions— list where each checked template was defined-C dir— change working directory before loading packages-o format— output format:tsv(default) orjsonl
Call Execute with a types.Type for the template's data (.) and the template's parse.Tree. See example_test.go for a working example.
Package hands each inspector callback a Definition locating the template it is about to check. A Definition carries three Spans — the {{define}} or {{block}} clause, the matching {{end}}, and the quoted name literal inside the clause — along with the template's parse.Tree.
A Span embeds a token.Position and adds a byte Length, so it reports a file, line, column, offset and length with the same semantics as go/token. Note that parse.Tree.ErrorContext counts columns from zero instead, so the two differ by one.
IsBlock reports whether a {{block}} clause defined the template rather than a {{define}}, and BlockPipeline returns the pipeline that clause passes. text/template rejects a block written without one, so the pipeline's presence is what distinguishes the two.
Positions address real bytes in a real file. A template read by ParseFS resolves against the template file. A template written as a Go string literal resolves against the .go file holding it, with escape sequences accounted for, so {{define \"x\"}} reports the width of the escaped source rather than of the decoded text. A template file's own root template has no define clause, so it spans the whole file.
When a name is defined more than once, Definition reports the one that survived, applying the same rule text/template does: an empty definition does not displace one that already has a body.
muxt— builds on this library to type-check templates wired to HTTP handlers. If you only need command-line checks,muxt checkworks too.- jba/templatecheck — a reflect based alternative for template type-checking maintained by a Go team member.
- You must provide a
types.Typefor the template's root context (.). - No support for third-party template packages (e.g. safehtml).
- Cannot detect runtime conditions such as out-of-range indexes or errors from boxed types.