plugins

Plugins

Template::HAML::Plugin is the public surface for bundling related hooks — visitors, tag transformers, filters, and the markdown backend — into a single artifact that can be installed and removed atomically.

Why bundle?

Each hook registry exposes its own register-* / clear-* subs. They work fine for one-off use, but a plugin author shipping several related hooks needs every hook installed before the first render and every hook removed on uninstall. The Plugin class makes that bookkeeping the framework's responsibility:

  • install runs every registration sub in declaration order.

  • uninstall removes exactly the hooks this plugin registered, by name.

  • clear-plugins uninstalls every plugin in reverse-install order.

Declaring a plugin

use Template::HAML::Plugin;

my $bootstrap = Template::HAML::Plugin::Plugin.new(
  :name<bootstrap-helpers>,
  :visitors([
    %( :name<inject-meta>, :handler(-> $tree { ... ; $tree }) ),
  ]),
  :tag-transformers([
    %( :name<card>, :handler(-> $node {
      $node.object.name = 'div';
      $node.object.attrs.push: 'class' => 'card';
      $node;
    }) ),
  ]),
  :filters([
    %( :name<upper>, :handler(-> Str $body, %locals --> Str { $body.uc }) ),
  ]),
  :markdown-backend(-> Str $body --> Str { ... }),
);

install-plugin($bootstrap);
# ... render with hooks active

uninstall-plugin($bootstrap);

Every visitor, tag-transformer, and filter entry must be a hash with :name and :handler keys. Both are validated at Plugin.new time, so a malformed manifest fails at construction rather than mid-render. Plugin-registered visitors are always named (so uninstall can find them) — anonymous visitors are only available through Template::HAML::Visitor::register-visitor directly.

Lifecycle guarantees

The plugin lifecycle is stable. These properties are public API and won't change without a major version bump:

  1. Registration order is preserved. Inside one plugin, visitors run in the order they appear in the :visitors list. Across plugins, visitors run in plugin-install order, then per-plugin order. The same applies to filter and tag-transformer registration: later wins on name collision.

  2. Install is idempotent. Calling install-plugin($p) on an already installed plugin is a no-op. The plugin doesn't appear twice in installed-plugins().

  3. Uninstall is idempotent. Calling uninstall-plugin($p) on a not-installed plugin is a no-op.

  4. Uninstall is by name. Uninstalling a plugin clears the hooks it registered by name. If a different plugin (or direct registration) later overrode that name, uninstalling the original plugin removes the currently-registered handler for that name. Plugins that share hook names are co-operating, not isolated.

  5. clear-plugins() uninstalls in reverse install order. Returns the number of plugins it removed.

  6. Hooks observe the same pipeline order as before: parse → visitors → tag transformers → render. Filters resolve per :name line at render time. Tag transformers and visitors run before code generation, so compile-source-to-raku and the on-disk cache reflect the transformed tree. Installing or uninstalling a plugin auto-invalidates the in-process direct-emit and compiled-&fn caches; call clear-compiled-cache if you also need the on-disk cached .rakumod artifacts rebuilt.

Inspecting installed plugins

my @plugins = installed-plugins();        # list of Plugin objects
my @names   = installed-plugin-names();   # list of Str
my $maybe   = installed-plugin('card');   # Plugin or type object
my Int $n   = clear-plugins();            # uninstall all, return count

installed-plugin($name) returns the Plugin type object (undefined) when no plugin with that name is installed — guard with .defined.

What is not a plugin

  • Render-time helpers — those go through the :context object. See Render context.

  • Configuration overrides — use Template::HAML::Config. See Configuration.

  • Per-template scope additions — use :%locals or :context on render.

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.