Overview of the bbmustache application
masterbbmustache module.repository·master·Indexed 41 days ago
https://github.com/soranoba/bbmustacheA logic-less binary pattern match-based Mustache template engine for Erlang/OTP. It avoids regular expressions for improved performance and reliability, providing compliance with the Mustache v1.4.1 specification. Features include support for maps and associative arrays as data sources, custom HTML escaping via escape_fun, and a two-phase parse and compile process (using parse_binary/1, parse_file/1, and compile/2) to optimize rendering performance.
bbmustache module.By default, bbmustache escapes HTML characters. You can control this in two ways:
{{{tag}}} in your template to render unescaped content.escape_fun option in bbmustache:render/3 to provide a custom escaping logic (or an identity function to disable it entirely).%% Use triple braces for unescaped output
1> bbmustache:render(<<"<h1>{{{title}}}</h1>">>, #{"title" => "I like Erlang & mustache"}).
<<"<h1>I like Erlang & mustache</h1>">
%% Use escape_fun to disable escaping
1> bbmustache:render(<<"<h1>{{title}}</h1>">>, #{"title" => "I like Erlang & mustache"}, [{escape_fun, fun(X) -> X end}]).
<<"<h1>I like Erlang & mustache</h1>">>In bbmustache, keys used in templates follow specific rules:
.):parent.child: Used to find the child key within the parent context.. (single dot): Represents the current context.When using recursive_data(), you can choose the key type (atom, binary, or string) via key_type in compile_option().
You can run the benchmark script to compare the performance of bbmustache against other implementations like mustache.erl. The benchmark script is provided as an .escript file.
escript bench.escriptTo use bbmustache in your Erlang project, add it to your dependency manager configuration.
For rebar (rebar.config): Use the git dependency pointing to the master branch.
For rebar3 (rebar.config):
Add bbmustache to your deps list.
%% rebar (rebar.config)
{deps,
[
{bbmustache, ".*", {git, "https://github.com/soranoba/bbmustache.git", {branch, "master"}}}
]}.
%% rebar3 (rebar.config)
{deps, [bbmustache]}.To optimize performance, separate the parsing phase from the rendering phase. This avoids re-parsing the template structure for every render operation.
bbmustache:parse_binary/1 to parse a binary template.bbmustache:parse_file/1 to parse a template from a file.bbmustache:compile/2 to render the parsed template with your data.%% Using parsed binary
Template1 = bbmustache:parse_binary(<<"{{name}}">>).
Result = bbmustache:compile(Template1, #{"name" => "hoge"}).
%% Using parsed file
Template2 = bbmustache:parse_file(<<"./hoge.mustache" >>).
Result = bbmustache:compile(Template2, [{"name", "hoge"}]).The bbmustache:render/2 function performs a quick render of a binary template using a data source. The bbmustache:render/3 function allows passing an additional list of options.
Supported data sources:
#{key => value}[{key, value}]Options available in render/3:
escape_fun: A function used to handle HTML escaping. To disable escaping, provide an identity function: fun(X) -> X end.key_type: Specifies the type of keys to expect in the data source (atom or binary).value_serializer: A function used to transform Erlang terms before rendering. This is useful for custom serialization (e.g., JSON encoding).Note on performance: For better performance, use parse_binary/1 or parse_file/1 to create a template once, then use compile/2 to render it multiple times with different data.
%% Quick render with a map
1> bbmustache:render(<<"{{name}}">>, #{"name" => "hoge"}).
<<"hoge">
%% Quick render with an associative array
1> bbmustache:render(<<"{{name}}">>, [{"name", "hoge"}]).
<<"hoge">
%% Render with custom escaping
1> bbmustache:render(<<"<h1>{{title}}</h1>">>, #{"title" => "I like Erlang & mustache"}, [{escape_fun, fun(X) -> X end}]).
<<"<h1>I like Erlang & mustache</h1>">>
%% Render with custom key type and value serializer
1> bbmustache:render(<<"<h1>{{{title}}}</h1>">>, #{title => #{<<"nested">> => <<"value">>}}, [{key_type, binary}, {value_serializer, fun(X) -> jsone:encode(X) end}]).
<<"<h1>{\"nested\": \"value\"}</h1>">>Use bbmustache:parse_binary/2 to create a template() object from a binary string. You can provide parse_option() to customize how partials are handled.
Available parse_option() values:
partial_file_reader: A function fun((Dirname::binary(), Key::key()) -> Data::binary()) that delegates reading of partial files. This allows reading partials from sources other than the local file system.raise_on_partial_miss: If a template used in a partial is not found, an exception is thrown.Template = bbmustache:parse_binary(<<"{{name}}">>).
%% Or with options:
Template = bbmustache:parse_binary(<<"{{name}}">>, [raise_on_partial_miss]).Use bbmustache:parse_file/2 to create a template() object from a file on disk. You can provide parse_option() to customize partial loading.
Available parse_option() values:
partial_file_reader: A function fun((Dirname::binary(), Key::key()) -> Data::binary()) to delegate reading of partial files.raise_on_partial_miss: Throws an exception if a partial template is not found.Template = bbmustache:parse_file("template.mustache").
%% Or with options:
Template = bbmustache:parse_file("template.mustache", [raise_on_partial_miss]).Use bbmustache:compile/3 to embed data into a template. The data can be an associative array or a map, but all keys must be of the same type. You can provide compile_option() to customize behavior.
Available compile_option() values:
key_type: Specify the type of the key in data/0. Default is string.raise_on_context_miss: If a key exists in the template but not in the data, an exception is thrown.escape_fun: A custom function fun((binary()) -> binary()) for escaping.value_serializer: A custom function fun((any()) -> iodata()) to convert terms to iodata during templating.Template = bbmustache:parse_binary(<<"{{name}}">>).
bbmustache:compile(Template, #{name => "Alice"}).
%% Result: <<"Alice">>Use bbmustache:render/3 to render a raw binary template using provided data and options. This is functionally equivalent to parsing the binary into a template and then calling compile/3.
render(Bin, Data, Options) is equivalent to compile(parse_binary(Bin), Data, Options).
Available render_option() values:
compile_option(): See Compile a template with data for details.parse_option(): See Configure partial file reading for details.%% Equivalent to:
bbmustache:render(<<"{{name}}">>, #{name => "Alice"}, []).The benchmarks/README.md file contains a detailed comparison matrix of how bbmustache implements various parts of the Mustache v1.4.1 specification compared to mustache.erl. This includes compliance for: