Lavash.TagEngine behaviour (Lavash v0.3.0-rc.0)

Copy Markdown View Source

A fork of Phoenix.LiveView.TagEngine v1.1.27 with token transformer hooks.

Changes from upstream

  1. Module renamed to Lavash.TagEngine
  2. init/1 accepts :token_transformer and :lavash_metadata options
  3. handle_body/1 and handle_end/1 apply token transformer after tokens are finalized/reversed but before processing
  4. handle_body/1 wraps annotate_body in try/rescue for compatibility
  5. Self-references updated to Lavash.TagEngine

Summary

Callbacks

Callback invoked to add annotations around the whole body of a template.

Callback invoked to add caller annotations before a function component is invoked.

Callback invoked to add annotations around each slot of a template.

Classify the tag type from the given binary.

Implements processing of attributes.

Returns if the given tag name is void or not.

Functions

Compiles the given string into Elixir AST.

Compiles pre-tokenized HTML tokens directly into %Rendered{} AST.

Renders a component defined by the given function.

Define a inner block, generally used by slots.

Tokenizes a template source string into HTML tokens without compiling.

Callbacks

annotate_body(caller)

@callback annotate_body(caller :: Macro.Env.t()) :: {String.t(), String.t()} | nil

Callback invoked to add annotations around the whole body of a template.

annotate_caller(file, line)

@callback annotate_caller(file :: String.t(), line :: integer()) :: String.t() | nil

Callback invoked to add caller annotations before a function component is invoked.

annotate_slot(name, tag_meta, close_tag_meta, caller)

@callback annotate_slot(
  name :: atom(),
  tag_meta :: %{line: non_neg_integer(), column: non_neg_integer()},
  close_tag_meta :: %{line: non_neg_integer(), column: non_neg_integer()},
  caller :: Macro.Env.t()
) :: {String.t(), String.t()} | nil

Callback invoked to add annotations around each slot of a template.

In case the slot is an implicit inner block, the tag meta points to the component.

classify_type(name)

@callback classify_type(name :: binary()) :: {type :: atom(), name :: binary()}

Classify the tag type from the given binary.

This must return a tuple containing the type of the tag and the name of tag. For instance, for LiveView which uses HTML as default tag handler this would return {:tag, 'div'} in case the given binary is identified as HTML tag.

You can also return {:error, "reason"} so that the compiler will display this error.

handle_attributes(ast, meta)

@callback handle_attributes(ast :: Macro.t(), meta :: keyword()) ::
  {:attributes, [{binary(), Macro.t()} | Macro.t()]} | {:quoted, Macro.t()}

Implements processing of attributes.

It returns a quoted expression or attributes. If attributes are returned, the second element is a list where each element in the list represents one attribute. If the list element is a two-element tuple, it is assumed the key is the name to be statically written in the template. The second element is the value which is also statically written to the template whenever possible (such as binaries or binaries inside a list).

void?(name)

@callback void?(name :: binary()) :: boolean()

Returns if the given tag name is void or not.

That's mainly useful for HTML tags and used internally by the compiler. You can just implement as def void?(_), do: false if you want to ignore this.

Functions

compile(source, options)

Compiles the given string into Elixir AST.

The accepted options are:

  • tag_handler - Required. The module implementing the Lavash.TagEngine behavior.
  • caller - Required. The Macro.Env.
  • line - the starting line offset. Defaults to 1.
  • file - the file of the template. Defaults to "nofile".
  • indentation - the indentation of the template. Defaults to 0.

compile_from_tokens(tokens, opts)

Compiles pre-tokenized HTML tokens directly into %Rendered{} AST.

Bypasses the EEx → handle_text tokenization loop. The tokens must be in the format produced by Phoenix.LiveView.Tokenizer (already finalized).

Options are the same as compile/2 plus:

  • :token_transformer - module implementing token transformation
  • :lavash_metadata - metadata passed to the token transformer
  • :source - original template source string (for error messages)
  • :subengine - the subengine module (defaults to Phoenix.LiveView.Engine)

component(func, assigns, caller)

Renders a component defined by the given function.

This function is rarely invoked directly by users. Instead, it is used by ~H and other engine implementations to render Phoenix.Components. For example, the following:

<MyApp.Weather.city name="Kraków" />

Is the same as:

<%= component(
      &MyApp.Weather.city/1,
      [name: "Kraków"],
      {__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
    ) %>

inner_block(name, list)

(macro)

Define a inner block, generally used by slots.

This macro is mostly used by custom HTML engines that provide a slot implementation and rarely called directly. The name must be the assign name the slot/block will be stored under.

If you're using HEEx templates, you should use its higher level <:slot> notation instead. See Phoenix.Component for more information.

tokenize(source, options)

Tokenizes a template source string into HTML tokens without compiling.

Runs the full EEx + HTML tokenization pipeline (including EEx block handling) but stops after producing the finalized token list. Returns the tokens that would normally be passed to continue%Rendered{}.

This is used by the transformer pipeline to tokenize once, analyze tokens for derive extraction, then compile later via compile_from_tokens.