cli
Command-line interface
Template::HAML ships with a haml script for rendering and checking templates from the shell.
Subcommands
| Command | Purpose |
|---|---|
haml render | Render one or more HAML files to HTML. |
haml check | Parse-only sanity check; non-zero exit on parse failure. |
haml fmt | Pretty-print a HAML file in canonical form. |
haml lint | Static analysis; non-zero exit on diagnostics. |
haml help | Top-level help. Also --help, -h. |
Rendering
haml render view.hamlOutput goes to standard out. Multiple files are concatenated in the order given. To write the result to a file, pass -o:
haml render view.haml -o view.htmlReading from stdin
A file argument of - reads HAML source from standard input. This composes with the usual flags:
echo '%p hi' | haml render -
cat view.haml | haml render --locals name=Alice -- may appear at most once per invocation. Parse errors on stdin are reported against the label <stdin>.
Passing locals
Use --locals with a comma-separated list of key=value pairs:
haml render greet.haml --locals name=Alice,greeting=hiThe values are made available as Raku scalars inside the template (e.g. #{$name}).
Format and escaping
| Flag | Effect |
|---|---|
--format html5 | HTML5 output (default). |
--format html4 | HTML 4.01 Transitional. |
--format xhtml | XHTML 1.0 Transitional; void elements emit <br />. |
--escape-html | Escape HTML in = expressions (default). |
--no-escape-html | Disable HTML escaping for = expressions. |
--ugly | Single-line output with no inter-tag whitespace. |
--stream | Stream output incrementally; one chunk per top-level node. |
Streaming output
--stream writes HTML to its destination as each top-level node finishes
rendering, instead of buffering the whole document and writing once. It is
useful when piping into a slow consumer or when the document is large enough
that first-byte latency matters.
haml render --stream view.haml
haml render --stream view.haml -o view.html
echo '%p hi' | haml render --stream -Rendering multiple files
File arguments may be globs (e.g. 'views/*.haml'). The glob is expanded by haml itself when it contains * or ?; quoting prevents the shell from expanding it first, which matters in watch mode (see below).
When more than one file is rendered, output goes to --out-dir <dir>. Each input is mirrored to <dir>/<basename>.html:
haml render 'views/*.haml' --out-dir build/--out-dir and -o are mutually exclusive. With a single input, either works; with multiple inputs, only --out-dir is accepted.
Watch mode
haml render view.haml -o view.html --watch
haml render 'views/*.haml' --out-dir build/ --watch--watch does an initial render of every matching input, then re-renders any file that changes on disk. The watcher runs until interrupted (Ctrl-C). --watch requires -o or --out-dir ā there is no stdout streaming form.
By default the watcher uses Raku's IO::Notification (FSEvents on macOS, inotify on Linux). On filesystems where notifications are unreliable (NFS, some VM shared folders), pass --poll <ms> to fall back to mtime polling:
haml render 'views/*.haml' --out-dir build/ --watch --poll 200Watch mode does not accept a - (stdin) argument.
Checking
haml check view.hamlcheck parses each file and reports OK for files that parse cleanly. It exits with a non-zero status if any file fails to parse, so it is suitable for use in pre-commit hooks or CI.
Formatting
haml fmt view.hamlfmt pretty-prints each HAML file in canonical form and writes the result to standard out. Use the following flags to change behavior:
| Flag | Effect |
|---|---|
-o <path> | Write the formatted result to a file (single input only). |
--in-place | Rewrite each input file with its canonical form. |
--check | Exit non-zero if any file differs from its canonical form. No output. |
--check mode is suitable for CI: it emits no stdout, writes a one-line diagnostic to stderr for each non-canonical file, and exits with status 1 when at least one file is out of form. --in-place and -o are mutually exclusive, and neither may be combined with --check.
The canonical form is idempotent: haml fmt | haml fmt always equals haml fmt. See the canonical form spec for the full set of rules.
Linting
haml lint view.hamllint parses each HAML file and runs the registered lint rules over the parse tree and source. Diagnostics are written to standard out, one per line, in the form:
path:line:col: severity: message (rule-id)A file argument of - reads source from standard input; the diagnostic path becomes <stdin>.
Exit codes
| Code | Meaning |
|---|---|
0 | No diagnostics reported. |
1 | At least one diagnostic reported, or a file failed to parse. |
2 | Invocation error (bad option, missing file argument). |
Built-in rules
| Rule | What it catches |
|---|---|
deprecated-syntax | Use of the dropped :ruby filter (suggests :raku). |
malformed-indent | Trailing whitespace on a line, and whitespace-only blank lines. |
unused-locals | A key in --locals that the template never references. |
Declaring expected locals
The unused-locals rule needs to know which locals the template will receive. Pass the expected keys with --locals (the same syntax as haml render); values are accepted but ignored:
haml lint --locals name,age,role view.hamlA key listed in --locals that is never referenced as $key in the template produces an unused-locals warning. Without --locals, the rule sleeps.
Extending the rule set
Library users can register additional rules:
use Template::HAML::Lint;
class MyRule does Template::HAML::Lint::Rule {
method id(--> Str) { 'my-rule' }
method check(:$tree, :$src, :%locals --> List) {
# ... return a list of Template::HAML::Lint::Diagnostic
}
}
Template::HAML::Lint::register-rule(MyRule.new);Registered rules run in addition to the built-ins. clear-rules() removes them.
Help
Each subcommand has its own help:
haml --help
haml render --help
haml check --help
haml lint --help
haml fmt --help