CHANGELOG

Changelog

All notable changes to this project will be documented in this file.

v0.9.5 — 2026-06-27

Added

  • Render context. HAML.render accepts a :context named argument whose methods become reachable inside templates as bare identifiers in expression position and control-flow conditions. Resolution order is locals, then context method, then the normal Raku evaluator.

  • Helpers with arguments. A context method is callable as a bare name with arguments (!= link-to('Home', '/')), dispatching to the context, in both the interpreted and direct-emit renderers.

  • User-provided helpers. Template::HAML::HelpersRole and Template::HAML::ViewContext are the two composition points for adding template-facing helpers. Mix the role into your own class to keep the built-in helpers, or subclass ViewContext.

  • Overriding built-ins. A context method takes precedence over the built-in helper of the same name, so replacing surround, list-of, partial, etc. for a render is just defining a method with that name.

  • Explicit helper declaration. A haml-helper-names method lets a context declare helpers that .^methods introspection cannot see, such as those added at runtime or served through FALLBACK.

v0.9.4 — 2026-05-31

Changed

  • CI test runs. The test suite is split across multiple parallel jobs so the pipeline finishes faster and failures are easier to localize.

  • CI benchmarks. The benchmark run moved into its own dedicated job, separate from the test jobs.

  • Ecosystem metadata. Packaging metadata tweaked so the distribution links correctly on raku.land.

v0.9.3 — 2026-05-25

Added

  • :layout for render-file-cached. Mirrors HAML.render(:file, :layout). Both the inner template and the layout are compiled, cached on disk, and memoized in-process independently; editing either file invalidates only that file's entry. The layout sees the inner render through = yield and yield(:name<...>) / content-for.

v0.9.2 — 2026-05-25

Changed

  • CI workflow. Added a name: and workflow_dispatch trigger so the pipeline can be re-run manually from the GitHub Actions UI.

  • CI dependencies. Dropped the explicit install step for BDD::Behave from git; it now resolves through normal --test-depends from the Raku ecosystem.

v0.9.1 — 2026-05-23

Added

  • Tag shorthand interpolation. #{...} and !{...} inside class and id shorthand (.#{cls}, ##{id}).

  • Object references. [obj] / [obj, :prefix] after a tag emits stable class and id derived from the object's type and identity.

  • Attribute splats. *%h and *@a inside {...} / (...) to merge hashes and pair-lists into the attribute set, with the same ordering and boolean rules as literal attributes.

  • Template codegen. Compile a parsed template to a reusable Raku sub via Template::HAML::Codegen, cached on disk and keyed on source + config.

  • Direct-emit codegen. Template::HAML::DirectEmit lowers templates to straight-line print / write calls for hot paths, bypassing the AST walker.

  • Streaming render. render-stream writes incrementally to any IO::Handle or Supplier, with backpressure-aware chunking.

  • Cross-process precompilation cache. Compiled templates persist under .precomp/ keyed on path + mtime + config hash and are reused across processes.

  • Cache invalidation. Mtime + config-hash checks invalidate stale entries; manual Template::HAML::Cache.clear for tests and dev loops.

  • Codegen error mapping. Runtime exceptions thrown from generated code map back to original template :file, :line, :column via a side-table.

  • Render-time scope. Locals, helpers, and content-for blocks share a single scope object so partials and layouts see consistent state.

  • Function memoization. Pure helpers can opt in to per-render memoization with is memoized.

  • Plugin API. Template::HAML::Plugin lets third-party packages register filters, helpers, doctypes, and tag transformers from a single entry point.

  • AST visitor hook. Template::HAML::Visitor exposes pre- and post-order walks over the parsed tree for linters, formatters, and analyzers.

  • Tag transformer registry. Register callbacks that rewrite tag nodes before codegen (e.g. auto-rel="noopener" on external links).

  • Pluggable markdown filter. :markdown filter backed by any registered markdown implementation; ships with a default adapter.

  • haml render. Render a template file or stdin to stdout / -o, with --locals, --format, --escape-html / --no-escape-html, --ugly.

  • haml fmt. Canonicalize indentation, attribute order, and quote style; --check exits non-zero on diff for CI.

  • haml lint. Static checks for duplicate ids, unused locals, illegal indentation, and unknown filters/doctypes.

  • --watch for CLI. Re-renders on file change with debounce.

  • Trace for template debugging. TEMPLATE_HAML_TRACE=1 annotates output with source positions as HTML comments.

  • String encoding validation. Non-UTF-8 input fails fast with a clear X::HAML::ParseFail instead of silently producing mojibake.

  • page-class helper. Emits a stable class attribute for the document body based on controller/action or template path.

  • Bench harness. bench/ scripts for parse, codegen, and render timings against a fixed corpus.

  • Meta-provides testing. AUTHOR_TESTING=1 checks every module under lib/ is listed in META6.json provides.

Changed

  • Interior whitespace. Runs of internal whitespace in plain text and attribute values are squeezed to a single space under :ugly output, matching Ruby HAML.

Fixed

  • Grammar bugs. Several edge cases around nested interpolation, attribute parsing, and indent re-entry after blank lines.

  • CI. Test matrix and dependency installation on GitHub Actions.

v0.9.0 — 2026-05-11

First release. Targets feature parity with Ruby HAML 5.x. Built on Raku Grammars.

Added

  • Grammar foundations. Line-type dispatch (tag, statement, comment, silent-comment, doctype, filter, plain, blank), CRLF normalization, indent-unit auto-detection with strict mixed-tab/space and inconsistent-indent errors, and source positions (file/line/column) threaded through every X::HAML::* exception.

  • Tag syntax. Implicit-div shorthand (.foo, #bar), combined explicit shorthand in any order (%tag.a.b#main), id concatenation with _, self-closing (explicit / and implicit for HTML void elements), inline-plus- block content, whitespace-removal modifiers (>, <, <>, ><), XML namespaced names, and custom-element names containing -.

  • Attributes. Hash form ({...}), HTML-style ((...)), old-style hash rocket ({:foo => 'bar'}), hyphenated string keys, data: / aria: shorthand with recursive expansion and optional camelCase → kebab-case, boolean and Nil value rules, HTML escaping by default, configurable quote style, and stable attribute ordering.

  • Embedded Raku code. =, -, !=, &=, == output operators backed by a cached EVAL substrate; multiline continuation on trailing comma or unbalanced brackets; errors wrapped in X::HAML::Eval with source position.

  • Control flow. if / unless / elsif / else, for, while (capped), given / when / default, and repeat N. Loop variables are scoped to the block.

  • Plain text and interpolation. #{...} (escaped) and !{...} (raw) in tag content, attribute values, and plain text; backslash escape; no legacy | continuation.

  • Comments. HTML comments (/), conditional comments (/[if IE]), revealed conditional, and silent comments (-#) whose children are opaque.

  • Doctypes. !!! with 5, 1.1, Strict, Frameset, Mobile, RDFa, Basic, XML, and XML <encoding> variants; format-aware defaults.

  • Filters. Pluggable registry (Template::HAML.register-filter) with built-ins: :plain, :escaped, :javascript, :css, :cdata, :preserve, :raku. Interpolation rules match Ruby HAML per filter.

  • Configuration. Template::HAML::Config covering format (:html5 / :html4 / :xhtml), escape_html, escape_attrs, output-style (:pretty / :ugly), autoclose, preserve, encoding, cdata, mime_type, suppress_eval, and attr_quote.

  • Whitespace operators. Outer (>), inner (<), combined, and ~ expr to force preserve on a single tag; find-and-preserve helper.

  • Helpers. capture-haml, haml-concat, surround, precede, succeed, tab-up / tab-down, find-and-preserve, escape-once, html-safe, list-of.

  • Layouts and partials. = yield (named and unnamed), content-for, = render :partial<name> with :locals, :collection / :as, search-path resolution, and a per-process compile cache keyed on path + mtime.

  • Errors. X::HAML::ParseFail, IndentMixed, IndentInconsistent, UnknownFilter, UnknownDoctype, Eval, TemplateNotFound, DuplicateId, IllegalIndent, each carrying :file, :line, :column, :snippet. Parse failures render a one-line caret-pointer snippet.

  • CLI. haml render (with -o, --locals, --format, --escape-html / --no-escape-html, --ugly), haml check, haml --help, and per-subcommand help.

Template::HAML v0.9.5

HAML template engine

Authors

  • Greg Donald

License

Artistic-2.0

Dependencies

Provides

  • Template::HAML
  • Template::HAML::Actions
  • Template::HAML::CLI
  • Template::HAML::Cache
  • Template::HAML::Codegen
  • Template::HAML::Comment
  • Template::HAML::Config
  • Template::HAML::Context
  • Template::HAML::DirectCodegen
  • Template::HAML::DirectEmit
  • Template::HAML::Doctype
  • Template::HAML::Eval
  • Template::HAML::Filter
  • Template::HAML::Filters
  • Template::HAML::Format
  • Template::HAML::Grammar
  • Template::HAML::Helpers
  • Template::HAML::HelpersRole
  • Template::HAML::Interpolation
  • Template::HAML::Lint
  • Template::HAML::Multiline
  • Template::HAML::Node
  • Template::HAML::Plain
  • Template::HAML::Plugin
  • Template::HAML::Renderer
  • Template::HAML::Statement
  • Template::HAML::Tag
  • Template::HAML::TagTransformers
  • Template::HAML::ViewContext
  • Template::HAML::Visitor
  • Template::HAML::Watch
  • Template::HAML::X

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.