klenod.

Plugin Reference

HamlPlugin

HamlPlugin turns `.haml` files into components for your rendering framework.

Configuration

Configure the component class, element factory, children, variables, and translations:

Klenod::Build::Plugins::HamlPlugin.new(
  component_base_class: "Example::Framework::Component",
  factory: "Example::Framework::H",
  component_children: :lazy,
  variables: {
    global: "@__props",
    class: "Example::Framework::Context.current",
    instance: "@__state"
  },
  i18n: {
    class: "Example::Framework::Translator",
    constant: "I18n"
  },
  cache_static_subtrees: false
)

Options

  • component_base_class sets the superclass of each generated component.
  • factory receives every HTML tag and component call.
  • component_children controls how component children are passed. Use :eager for positional arguments or :lazy for a block.
  • variables maps Haml variables to framework-owned objects. It accepts global, class, and instance.
  • i18n configures translations. class creates the helper. constant names it.
  • cache_static_subtrees reuses frozen element trees that contain no dynamic values. This is an experimental optimization.

Variables

Each variable becomes indexed access on its configured receiver:

%h1= $title
%p= @@request.path
%button= @count

With the configuration above, these read (@__props)[:title], (Example::Framework::Context.current)[:request], and (@__state)[:count].

The mappings also apply to assignments. For an indexed state store, reassign mutable values to trigger its assignment method. Use @items = [*@items, item] instead of @items << item.

Unconfigured variable kinds keep their normal Ruby behavior. Special globals such as $!, $1, and $LOAD_PATH are never remapped. Neither are underscore-prefixed instance variables such as @__state.

Component Children

Eager children are positional factory arguments:

Example::Framework::H[Card, Example::Framework::H[:p, "Body"], title: "Hello"]

Lazy children are passed as a block:

Example::Framework::H[Card, title: "Hello"] do
  [Example::Framework::H[:p, "Body"]]
end

Lazy children let components defer work, provide context, or collect slots. The factory should memoize the block if it may read the children more than once.

Components, Ruby, And Filters

Imported constants can be used as tags. For example, %Button passes the imported Button class to the factory. Custom elements imported through JavaScriptPlugin work the same way.

Top-level :ruby defines imports, constants, and methods. Other Ruby blocks run while the component renders.

= prints a value, - runs code silently, and printed Ruby blocks such as = if condition render their Haml body.

:markdown filters use MarkdownPlugin. :css filters add inline styles to the module graph.

Companions

A matching .css file adds scoped class and tag names through CSSPlugin:

components/Card.haml
components/Card.css

Matching translation files are loaded through IntlPlugin:

components/Card.intl.en.toml
components/Card.intl.sv.toml

With i18n, the plugin creates the configured helper constant:

I18n = Example::Framework::Translator.new(self)

The example translator provides I18n.t(...) and I18n.lang. Haml also works without IntlPlugin or a translation helper.

Errors

Source maps point runtime errors back to Haml. Parse errors include the original source. Companion and inline CSS keep their own source maps.