CHANGELOG
Changelog
All notable changes to this project will be documented in this file.
v0.9.5 ā 2026-06-27
Added
Render context.
HAML.renderaccepts a:contextnamed 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::HelpersRoleandTemplate::HAML::ViewContextare the two composition points for adding template-facing helpers. Mix the role into your own class to keep the built-in helpers, or subclassViewContext.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-namesmethod lets a context declare helpers that.^methodsintrospection cannot see, such as those added at runtime or served throughFALLBACK.
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
:layoutforrender-file-cached. MirrorsHAML.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= yieldandyield(:name<...>)/content-for.
v0.9.2 ā 2026-05-25
Changed
CI workflow. Added a
name:andworkflow_dispatchtrigger so the pipeline can be re-run manually from the GitHub Actions UI.CI dependencies. Dropped the explicit install step for
BDD::Behavefrom git; it now resolves through normal--test-dependsfrom 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 stableclassandidderived from the object's type and identity.Attribute splats.
*%hand*@ainside{...}/(...)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::DirectEmitlowers templates to straight-lineprint/writecalls for hot paths, bypassing the AST walker.Streaming render.
render-streamwrites incrementally to anyIO::HandleorSupplier, 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.clearfor tests and dev loops.Codegen error mapping. Runtime exceptions thrown from generated code map back to original template
:file,:line,:columnvia a side-table.Render-time scope. Locals, helpers, and
content-forblocks 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::Pluginlets third-party packages register filters, helpers, doctypes, and tag transformers from a single entry point.AST visitor hook.
Template::HAML::Visitorexposes 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.
:markdownfilter 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;--checkexits non-zero on diff for CI.haml lint. Static checks for duplicate ids, unused locals, illegal indentation, and unknown filters/doctypes.--watchfor CLI. Re-renders on file change with debounce.Trace for template debugging.
TEMPLATE_HAML_TRACE=1annotates output with source positions as HTML comments.String encoding validation. Non-UTF-8 input fails fast with a clear
X::HAML::ParseFailinstead of silently producing mojibake.page-classhelper. Emits a stableclassattribute 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=1checks every module underlib/is listed inMETA6.jsonprovides.
Changed
Interior whitespace. Runs of internal whitespace in plain text and attribute values are squeezed to a single space under
:uglyoutput, 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 everyX::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 andNilvalue rules, HTML escaping by default, configurable quote style, and stable attribute ordering.Embedded Raku code.
=,-,!=,&=,==output operators backed by a cachedEVALsubstrate; multiline continuation on trailing comma or unbalanced brackets; errors wrapped inX::HAML::Evalwith source position.Control flow.
if/unless/elsif/else,for,while(capped),given/when/default, andrepeat 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.
!!!with5,1.1,Strict,Frameset,Mobile,RDFa,Basic,XML, andXML <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::Configcoveringformat(:html5/:html4/:xhtml),escape_html,escape_attrs,output-style(:pretty/:ugly),autoclose,preserve,encoding,cdata,mime_type,suppress_eval, andattr_quote.Whitespace operators. Outer (
>), inner (<), combined, and~ exprto force preserve on a single tag;find-and-preservehelper.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.