Mustache GitHub

Mustache.jl#

Documentation for Mustache.jl.

Examples#

Following the main documentation for Mustache.js we have a "typical Mustache template" defined by (along with a bit of an anti-tax sentiment):

using Mustache

tpl = mt"""
Hello {{name}}
You have just won {{value}} dollars!
{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}
"""
MustacheTokens
Mustache.TextToken("text", "Hello ")
Mustache.TagToken("name", "name", "{{", "}}", "")
Mustache.TextToken("text", "\nYou have just won ")
Mustache.TagToken("name", "value", "{{", "}}", "")
Mustache.TextToken("text", " dollars!\n")
SectionToken("#", "in_ca", "{{", "}}")
  Mustache.TextToken("text", "Well, ")
  Mustache.TagToken("name", "taxed_value", "{{", "}}", "")
  Mustache.TextToken("text", " dollars, after taxes.\n")

The values with braces (mustaches on their side) are looked up in a view, such as a dictionary or module. For example,

d = Dict(
"name" => "Chris",
"value" => 10000,
"taxed_value" => 10000 - (10000 * 0.4),
"in_ca" => true)

Mustache.render(tpl, d) |> print
Hello Chris
You have just won 10000 dollars!
Well, 6000.0 dollars, after taxes.

The render function pieces things together. Like print, the first argument is for an optional IO instance. In the above example, where one is not provided, a string is returned. (The print call is for formatting purposes.)

The flow is

  • a template is parsed into tokens by Mustache.parse. This can be called directly, indirectly through the non-standard string literal mt, the non-standard string literal jmt (which allows for string interpolation), or when loading a file with Mustache.load. The templates use tags comprised of matching mustaches ({}), either two or three, to indicate a value to be substituted for. These particular symbols indicating tags may be adjusted when parse is called.

  • The tokens and a view are rendered into a string. The render function takes tokens as its second argument. If this argument is a string, parse is called internally. The render function than reassambles the template, substituting values, as appropriate, from the "view" passed to it and writes the output to the specified io argument.

There are only 4 exports: mt and jmt (string literals to specify a template), render, and render_from_file.

The pipeline#

A template is specified and rendered with values coming from a view. This section gives some more detail.

Rendering#

The render function combines tokens and a view to fill in the template. The basic call is render([io::IO], tokens, view), however there are variants:

  • render(tokens; view...)

  • render(tokens; kwargs...)

Or (wherestring is parsed into tokens before rendering):

  • render(string, view)

  • render(string; kwargs...)

MustacheTokens objects are functors; keyword arguments can also be passed to a Tokens object directly which resolves to calling render.

  • tokens([io::IO], view)

  • tokens([io::IO]; kwargs...)

For example:

goes_together = mt"{{{:x}}} and {{{:y}}}."
goes_together(; x="Fish", y="chips")
"Fish and chips."

Views#

Views are used to hold values for the templates variables. There are many possible objects that can be used for views:

  • a dictionary

  • a named tuple

  • keyword arguments to render

  • a composite type

  • a module

  • data frame

The tags are looked up in the context of a view, so the view is used to provide values to substitute into the template. The lookup allows for different types of view. The above example used a dictionary. A Module may also be used, such as Main:

name, value, taxed_value, in_ca = "Christine", 10000, 10000 - (10000 * 0.4), false
Mustache.render(tpl, Main) |> print
Hello
You have just won  dollars!

Which yields:

Hello Christine
You have just won 10000 dollars!

Similarly, a named tuple may be used as a view.

tpl(; name="Bill", value=1, taxed_value =0.5, in_ca = true) |> print
Hello Bill
You have just won 1 dollars!
Well, 0.5 dollars, after taxes.

As well, one can use composite types. This could make writing show methods easier (though string interpolation is as easy in this example):

using Distributions
tpl = "Beta distribution with alpha={{α}}, beta={{β}}"
Mustache.render(tpl, Beta(1, 2))
"Beta distribution with alpha=1.0, beta=2.0"

Further, keyword arguments can be used when the variables in the templates are symbols:

goes_together = mt"{{{:x}}} and {{{:y}}}."
Mustache.render(goes_together; x="Salt", y="pepper")
Mustache.render(goes_together; x="Bread", y="butter")
"Bread and butter."

Multiple views#

Support for more than one view is also provided. A simple example with two named tuples is:

tpl = mt"""{{:a}} {{:b}} {{:c}}"""
tpl((;a=1, b=2), (;c=3))
"1 2 3"

When competing views specify the same value, the resolution comes from left to right with keyword arguments overriding any positional argument:

tpl((;a=1, b=2, c=4), (;c=3)), tpl((;a=1, b=2, c=4), (;c=3); c=5)
("1 2 4", "1 2 5")

Templates and tokens#

A template is parsed into tokens.

  • Parsing is done at compile time, if the mt string literal is used to define the template. If re-using a template, this is encouraged, as it will be more performant.

mt"""
{{:x}} is  {{:y}}
"""
MustacheTokens
Mustache.TextToken("text", "")
Mustache.TagToken("name", ":x", "{{", "}}", "")
Mustache.TextToken("text", " is  ")
Mustache.TagToken("name", ":y", "{{", "}}", "")
Mustache.TextToken("text", "\n")
  • If string interpolation is desired prior to the parsing into tokens, the jmt string literal can be used.

x = "John"
jmt"""
$x is {{:y}}
"""
MustacheTokens
Mustache.TextToken("text", "John is ")
Mustache.TagToken("name", ":y", "{{", "}}", "")
Mustache.TextToken("text", "\n")

(This can prove useful if two passes through a template are needed.)

  • As well, a string can be used to define a template. When parse is called, the string will be parsed into tokens. This is the flow if render is called on a string (and not tokens).

Tags#

A template use tags to specify areas to be filled in by a view. There are numerous tag types, summarized in a table near the end of this document.

Variables#

Tags representing variables for substitution have the form {{varname}}, {{:symbol}}, or their triple-braced versions {{{varname}}} or {{{:symbol}}}.

The varname version will match variables in a view such as a dictionary or a module.

The :symbol version will match variables passed in via named tuple or keyword arguments; also dictionaries with symbols for keys.

b = "be"
Mustache.render(mt"a {{b}} c", Main)  # "a be c"
Mustache.render(mt"a {{:b}} c", b="bee") # "a bee c"
Mustache.render(mt"a {{:b}} c", (b="bee", c="sea")) # "a bee c"
"a bee c"

The triple brace prevents HTML substitution for entities such as <. The following are escaped when only double braces are used: "&", "<", ">", "'", "\", and "/".

Mustache.render(mt"a {{:b}} c", b = "%< bee >%")   # "a %&lt; bee &gt;% c"
Mustache.render(mt"a {{{:b}}} c", b = "%< bee >%") # "a %< bee >% c"
"a %< bee >% c"

If different tags are specified to parse, say << or >>, then <<{ and }>> indicate the prevention of substitution.

tokens = Mustache.parse("a <<:b>> c", ("<<", ">>"))
Mustache.render(tokens, b = "%< B >%")  # a %&lt; B &gt;% c"

tokens = Mustache.parse("a <<{:b}>> c", ("<<", ">>"))
Mustache.render(tokens, b = "%< B >%")  # "a %< B >% c"
"a %< B >% c"

If the variable refers to a function, the value will be the result of calling the function with no arguments passed in.

Mustache.render(mt"a {{:b}} c", b = () -> "Bea")  # "a Bea c"
"a Bea c"
using Dates
Mustache.render(mt"Written in the year {{:yr}}."; yr = year∘now) # "Written in the year 2023."
"Written in the year 2026."

Filtering#

This isn't part of the Mustache spec, but a filter can be applied to the value after it is looked up and before it is rendered. The tag syntax uses Julia's pipe operator, as in {{:varname |> functionname}}. The named function is looked up in the same view (or Main, then Base if not found) and is called with the resolved value.

Mustache.render(mt"Hello {{:name |> uppercase}}!", name="world", uppercase=uppercase)
"Hello WORLD!"

Inline anonymous functions are accepted too:

Mustache.render(mt"Hello {{:name |> x -> uppercase(x)}}!", name="world")
"Hello WORLD!"

A filter can be passed through the view if that flexibility is needed:

tpl = mt"Hello {{:name |> λ}}"
tpl(; name="world", λ=uppercase)
"Hello WORLD"

If this package is called from within a module, it might be necessary to pass in @__MODULE__ to the render function if a filter is defined within the current module.

Sections#

In the main example, the template included:

{{#in_ca}}
Well, {{taxed_value}} dollars, after taxes.
{{/in_ca}}

Tags beginning with #varname and closed with /varname create "sections." These have different behaviors depending on the value of the variable.

The syntax {{#varname |> f}} applies the function f to the looked up value of varname before applying the section logic.

Using a true(ish) value to conditionally display a section#

When the variable is not a function or a container the part between them is used only if the variable is defined and not "falsy:"

a = mt"{{#:b}}Hi{{/:b}}";
a(; b=true)  # "Hi"
a(; c=true)  # ""
a(; b=false) # "" also, as `b` is "falsy" (e.g., false, nothing, "")
""

The Mustache spec call itself "logicless" but using a filter can add logic. For example this pattern will only show the value of x if x is a number:

tpl = mt"{{# :x |> r -> isa(r, Number)}}{{:x}}{{/ :x}}"
tpl(; x = "one"), tpl(;, x=1)

Inverted section tags#

Related, if the tag begins with ^varname and ends with /varname the text between these tags is included only if the variable is not defined or is falsy.

Inverted tags may have a function call on the looked up value through the syntax {{^varname |> f}}.

This example will show only one of the statements:

tpl = mt"""
{{#:x |> >=(10)}} bigger than or equal 10 {{/:x}}
{{^:x |> >=(10)}} less than 10 {{/:x}}
"""
tpl(; x = 5) |> print

 less than 10

Using a function to modify the string within a section#

If the variable name refers to a function that function will be passed the unevaluated string within the section, as expected by the Mustache specification:

Mustache.render("{{#:a}}one{{/:a}}", a=length)  # "3"
"3"

The specification has been widened to accept functions of two arguments, the string and a render function:

tpl = mt"{{#:bold}}Hi {{:name}}.{{/:bold}}"
function bold(text, render)
    "<b>" * render(text) * "</b>"
end
tpl(; name="Tater", bold=bold) # "<b>Hi Tater.</b>"
"<b>Hi Tater.</b>"

If the tag "|" is used, the section value will be rendered first, an enhancement to the specification.

fmt(txt) = "<b>" * string(round(parse(Float64, txt), digits=2)) * "</b>";
tpl = """{{|:lambda}}{{:value}}{{/:lambda}} dollars.""";
Mustache.render(tpl, value=1.23456789, lambda=fmt)  # "<b>1.23</b> dollars."
"<b>1.23</b> dollars."

(Without the | in the tag, an error, ERROR: ArgumentError: cannot parse "{{:value}}" as Float64, will be thrown.)

Iteration in a section#

If the section variable, {{#varname}}, binds to an iterable collection, then the text in the section is repeated for each item in the collection with the view used for the context of the template given by the item.

This is useful for collections of named objects, such as DataFrames (where the collection is comprised of rows) or arrays of dictionaries. For Tables.jl objects the rows are iterated over.

Iterating over vectors#

Iterating over a associative array, like a dictionary or named tuple, the keys are used as variable name. Though it isn't part of the Mustache specification, when iterating over a vector or tuple—which have no obvious key save for index—Mustache.jl uses {{.}} to refer to the item:

tpl = mt"{{#:vec}}{{.}} {{/:vec}}"
Mustache.render(tpl, vec = ["A1", "B2", "C3"])  # "A1 B2 C3 "
"A1 B2 C3 "

Note the extra space after C3.

There is also limited support for indexing with the iteration of a vector that allows one to treat the last element differently. The syntax .[ind] refers to the value vec[ind]. (There is no support for the usual arithmetic on indices.)

To print commas one can use this pattern:

tpl = mt"{{#:vec}}{{.}}{{^.[end]}}, {{/.[end]}}{{/:vec}}"
Mustache.render(tpl, vec = ["A1", "B2", "C3"])  # "A1, B2, C3"
"A1, B2, C3"

To put the first value in bold, but no others, say:

tpl = mt"""
{{#:vec}}
{{#.[1]}}<bold>{{.}}</bold>{{/.[1]}}
{{^.[1]}}{{.}}{{/.[1]}}
{{/:vec}}
"""
Mustache.render(tpl, vec = ["A1", "B2", "C3"])  # basically "<bold>A1</bold>B2 C3"
"<bold>A1</bold>\n\n\nB2\n\nC3\n"

This was inspired by this question, but the syntax chosen was more Julian. This syntax – as implemented for now – does not allow for iteration. That is constructs like {{#.[1]}} don't introduce iteration, but only offer a conditional check.

Iterating over DataFrames or other Tables compatible objects#

For data frames, the rows are iterated over. Data frames in Julia have named columns, not rows. Here is a template for making a markdown table from a data frame. The first line shows a filter applied to an iterable in a section tag. The second line shows function application to a variable. The rest shows nested iteration over unnamed elements.

tpl = mt"""
|{{#:d |> names}} {{.}} | {{/:d}}
|{{:d  |> r -> ":----|" ^ size(r,2)}}
{{#:d}}
|{{#.}}{{.}}|{{/.}}
{{/:d}}
: {{:TITLE}}
"""
MustacheTokens
Mustache.TextToken("text", "|")
SectionToken("#", ":d |> names", "{{", "}}")
  Mustache.TextToken("text", " ")
  Mustache.TagToken("name", ".", "{{", "}}", "")
  Mustache.TextToken("text", " | ")
Mustache.TextToken("text", "\n|")
Mustache.TagToken("name", ":d  |> r -> \":----|\" ^ size(r,2)", "{{", "}}", "")
Mustache.TextToken("text", "\n")
SectionToken("#", ":d", "{{", "}}")
  Mustache.TextToken("text", "|")
  SectionToken("#", ".", "{{", "}}")
    Mustache.TextToken("text", "")
    Mustache.TagToken("name", ".", "{{", "}}", "")
    Mustache.TextToken("text", "|")
  Mustache.TagToken("/", ".", "{{", "}}", "")
  Mustache.TextToken("text", "\n")
Mustache.TextToken("text", ": ")
Mustache.TagToken("name", ":TITLE", "{{", "}}", "")
Mustache.TextToken("text", "\n")

We illustrate on some synthetic data.

using DataFrames
d = DataFrame(names=["John", "Paul", "George", "Ringo"], hand=["right", "left", "right", "right"])
tpl(; d, TITLE="dominant hand") |> print

This can be compared to using an array of Dicts, convenient if you have data by the row:

A = [Dict("a" => "eh", "b" => "bee"),
     Dict("a" => "ah", "b" => "buh")]
tpl = mt"{{#:A}}Pronounce a as {{a}} and b as {{b}}. {{/:A}}"
Mustache.render(tpl, A=A) |> print
Pronounce a as eh and b as bee. Pronounce a as ah and b as buh.

Iterating when the value of a section variable is a function#

From the Mustache documentation, consider the template

tpl = mt"""{{#:beatles}}
* {{:makename}}
{{/:beatles}}
"""
MustacheTokens
Mustache.TextToken("text", "")
SectionToken("#", ":beatles", "{{", "}}")
  Mustache.TextToken("text", "* ")
  Mustache.TagToken("name", ":makename", "{{", "}}", "")
  Mustache.TextToken("text", "\n")

when beatles is a vector of named tuples (or some other Tables.jl object) and name is a function.

When iterating over beatles, name can reference the rows of the beatles object by name. In JavaScript, this is done with this.XXX. In Julia, the values are stored in the task_local_storage object (with symbols as keys) allowing the access. The Mustache.get_this function allows JavaScript-like usage:

function makename()
    this = Mustache.get_this()
    this.first * " " * this.last
end
beatles = [(first="John", last="Lennon"), (first="Paul", last="McCartney")]

tpl(; beatles, makename) |> print
* John Lennon
* Paul McCartney

Using a filter, this might be more explicitly done through:

mname(r) = r.first * " " * r.last
tpl = mt"""
{{# :beatles }}
* {{. |> mname }}
{{/ :beatles }}
"""
tpl(@__MODULE__; beatles) |> print   # pass module to lookup `mname` within
* John Lennon
* Paul McCartney

Conditional checking without iteration#

The section tag, #, checks for existence; pushes the object into the view; and then iterates over the object. For cases where iteration is not desirable; the tag type @ can be used.

Compare these:

struct RANGE
  range
end

tpl = mt"""
<input type="range" {{@:range}} min="{{start}}" step="{{step}}" max="{{stop}}" {{/:range}}>
""";

Mustache.render(tpl, RANGE(1:1:2))

tpl = mt"""
<input type="range" {{#:range}} min="{{start}}" step="{{step}}" max="{{stop}}" {{/:range}}>
""";

Mustache.render(tpl, RANGE(1:1:2)) # iterates over Range.range
"<input type=\"range\"  min=\"1\" step=\"1\" max=\"2\"  min=\"1\" step=\"1\" max=\"2\" >\n"

Additional features#

Non-eager finding of values#

A view might have more than one variable bound to a symbol. The first one found is replaced in the template unless the variable is prefaced with ~. This example illustrates:

d = Dict(:two=>Dict(:x=>3), :x=>2)
tpl = mt"""
{{#:one}}
{{#:two}}
{{~:x}}
{{/:two}}
{{/:one}}
"""
Mustache.render(tpl, one=d) # "2\n"
Mustache.render(tpl, one=d, x=1) # "1\n"
"1\n"

Were {{:x}} used, the value 3 would have been found within the dictionary Dict(:x=>3); however, the presence of {{~:x}} is an instruction to keep looking up in the specified view to find other values, and use the last one found to substitute in. (This is hinted at in this issue)

Partials#

Partials are used to include partial templates into a template.

Partials begin with a greater than sign, like {{> box.tpl }}. In this example, the file box.tpl is opened and inserted into the template, then populated. A full path may be specified.

They also inherit the calling context.

In this way you may want to think of partials as includes, imports, template expansion, nested templates, or subtemplates, even though those aren't literally the case here.

The partial specified by {{< box.tpl }} is not parsed, rather included as is into the file. This can be faster.

The variable can be a filename, as indicated above, or if not a variable. For example

tpl = """\"{{>partial}}\""""

Mustache.render(tpl, Dict("partial"=>"*{{text}}*","text"=>"content"))
"\"*content*\""

Summary of tags#

To summarize the different tags marking a variable or container:

  • {{variable}} does substitution of the value held in variable in the current view; escapes HTML characters. The double braces can be adjusted using Mustache.parse.

  • {{{variable}}} does substitution of the value held in variable in the current view; does not escape HTML characters. The outer pair of mustache braces can be adjusted using Mustache.parse.

  • {{&variable}} is an alternative syntax for triple braces (useful with custom braces)

  • {{~variable}} does substitution of the value held in variable in the outmost view

  • {{#variable}} is section syntax. Sections are closed by {{/variable}}. Depending on the type of variable, it specifies the following:

    • if variable is not a container or a function and is not absent or nothing will use the text between the matching tags, marked with {{/variable}}; otherwise that text will be skipped. (Like an if/end block.)

    • if variable is a function, it will be applied to contents of the section. Use of | instead of # will instruct the rendering of the contents before applying the function. The spec allows for a function to have signature (x, render) where render is used internally to convert. This implementation allows rendering when (x) is the single argument.

    • if variable is a Tables.jl compatible object (row wise, with named rows), will iterate over the values, pushing the named tuple to be the top-most view for the part of the template up to {{\variable}}.

    • if variable is a vector or tuple—for the part of the template up to {{\variable}}—will iterate over the values. Use {{.}} to refer to the (unnamed) values. The values .[end] and .[i], for a numeric literal, will refer to values in the vector or tuple. For tabular data, {{.}} can also be iterated over.

  • {{^variable}}/{{.variable}} tags will show the values when variable is not defined, or is nothing.

  • {{>partial}} will include the partial value into the template, filling in the template using the current view. The partial can be a variable or a filename (checked with isfile).

  • {{<partial}} directly include partial value into template without filling in with the current view.

  • {{!comment}} comments begin with a bang, !

Alternatives#

Julia provides some alternatives to this package which are better suited for many jobs:

  • For simple substitution inside a string there is string interpolation.

  • For piecing together pieces of text either the string function or string concatenation (the * operator) are useful. (Also an IOBuffer is useful for larger tasks of this type.)

  • For formatting numbers and text, the Formatting.jl package, the Format package, and the StringLiterals package are available.

  • The HypertextLiteral package is useful when interpolating HTML, SVG, or SGML tagged content.

Differences from Mustache.js#

This project deviates from Mustache.js in a few significant ways:

  • Julia structures are used, not JavaScript objects. As illustrated, one can use Dicts, Modules, DataFrames, functions, ...

  • In the Mustache spec, when lambdas are used as section names, the function is passed the unevaluated section:

template = "<{{#lambda}}{{x}}{{/lambda}}>"
data = Dict("x" => "Error!", "lambda" => (txt) ->  txt == "{{x}}" ? "yes" : "no")
Mustache.render(template, data) ## "<yes>", as txt == "{{x}}"
"<yes>"

The tag "|" is similar to the section tag "#", but will receive the evaluated section:

template = "<{{|lambda}}{{x}}{{/lambda}}>"
data = Dict("x" => "Error!", "lambda" => (txt) ->  txt == "{{x}}" ? "yes" : "no")
Mustache.render(template, data) ## "<no>", as "Error!" != "{{x}}"
"<no>"

Tags referencing variables can have a filter applied:

tpl = mt"""
{{:x}} --> {{:x |> uppercasefirst}} --> {{:x |> x-> uppercase(x[1:2]) * x[3:end]}} --> {{:x |> uppercase}}
"""
tpl(; x = "boo")  |> print
boo --> Boo --> BOo --> BOO

API#

Mustache.Mustache

source

Mustache

Mustache is a templating package for Julia based on Mustache.js. [ Docs ]

Mustache.load — Tuple{AbstractString, Vararg{Any}}

source
Mustache.load(filepath, args...)

Load file specified through filepath and return the compiled tokens. Tokens are memoized for efficiency,

Additional arguments are passed to Mustache.parse (for adjusting the tags).

Mustache.parse — Union{Tuple{Any}, Tuple{Any, Any}}

source

Mustache.parse(template, tags = ("{{", "}}"))

Parse a template into tokens.

  • template: a string containing a template

  • tags: the tags used to indicate a variable. Adding interior braces ({,}) around the variable will prevent HTML escaping. (That is for the default tags, {{{varname}}} is used; for tags like ("<<",">>") then <<{varname}>> is used.)

Extended

The template interprets tags in different ways. The string macro mt is used below to both parse (on construction) and render (when called).

Variable substitution.

Like basic string interpolation, variable substitution can be performed using a non-prefixed tag:

julia> using Mustache

julia> a = mt"Some {{:variable}}.";

julia> a(; variable="pig")
"Some pig."

julia> a = mt"Cut: {{{:scissors}}}";

julia> a(; scissors = "8< ... >8")
"Cut: 8< ... >8"

Both using a symbol, as the values to substitute are passed through keyword arguments. The latter uses triple braces to inhibit the escaping of HTML entities.

Tags can be given special meanings through prefixes. For example, to avoid the HTML escaping an & can be used:

julia> a = mt"Cut: {{&:scissors}}";

julia> a(; scissors = "8< ... >8")
"Cut: 8< ... >8"

Sections

Tags can create "sections" which can be used to conditionally include text, apply a function to text, or iterate over the values passed to render.

Include text

To include text, the # prefix can open a section followed by a / to close the section:

julia> a = mt"I see a {{#:ghost}}ghost{{/:ghost}}";

julia> a(; ghost=true)
"I see a ghost"

julia> a(; ghost=false)
"I see a "

The latter is to illustrate that if the variable does not exist or is "falsy", the section text will not display.

The ^ prefix shows text when the variable is not present.

julia> a = mt"I see {{#:ghost}}a ghost{{/:ghost}}{{^:ghost}}nothing{{/:ghost}}";

julia> a(; ghost=false)
"I see nothing"

Apply a function to the text

If the variable refers to a function, it will be applied to the text within the section:

julia> a = mt"{{#:fn}}How many letters{{/:fn}}";

julia> a(; fn=length)
"16"

The use of the prefix ! will first render the text in the section, then apply the function:

julia> a = mt"The word '{{:variable}}' has {{|:fn}}{{:variable}}{{/:fn}} letters.";

julia> a(; variable="length", fn=length)
"The word 'length' has 6 letters."

Variable tags may also apply a post-lookup function with |>:

julia> a = mt"Hello {{:name |> uppercase}}!";

julia> a(; name="world", uppercase=uppercase)
"Hello WORLD!"

This also works for section and inverted-section tags, applying the function before truthiness or iteration is decided.

Anonymous functions are also accepted:

julia> a = mt"Hello {{:name |> x -> uppercase(x)}}!";

julia> a(; name="world")
"Hello WORLD!"

Iterate over values

If the variable in a section is an iterable container, the values will be iterated over. Tables.jl compatible values are iterated in a row by row manner, such as this view, which is a tuple of named tuples:

julia> a = mt"{{#:data}}x={{:x}}, y={{:y}} ... {{/:data}}";

julia> a(; data=((x=1,y=2), (x=2, y=4)))
"x=1, y=2 ... x=2, y=4 ... "

Iterables like vectors, tuples, or ranges – which have no named values – can have their values referenced by a {{.}} tag:

julia> a = mt"{{#:countdown}}{{.}} ... {{/:countdown}} blastoff";

julia> a(; countdown = 5:-1:1)
"5 ... 4 ... 3 ... 2 ... 1 ...  blastoff"

Partials

Partials allow substitution. The use of the tag prefix > includes either a file or a string and renders it accordingly:

julia> a = mt"{{>:partial}}";

julia> a(; partial="variable is {{:variable}}", variable=42)
"variable is 42"

The use of the tag prefix < just includes the partial (a file in this case) without rendering.

Comments

Using the tag-prefix ! will comment out the text:

julia> a = mt"{{! ignore this comment}}This is rendered";

julia> a()
"This is rendered"

Multi-lne comments are permitted.

Mustache.render — Tuple{IO, Mustache.MustacheTokens, Vararg{Any}}

source
render([io], tokens, view)
render([io], tokens; kwargs...)
(tokens::MustacheTokens)([io]; kwargs...)

Render a set of tokens with a view, using optional io object to print or store.

Arguments

  • io::IO: Optional IO object.

  • tokens: Either Mustache tokens, or a string to parse into tokens

  • view: A view provides a context to look up unresolved symbols demarcated by mustache braces. A view may be specified by a dictionary, a module, a composite type, a vector, a named tuple, a data frame, a Tables object, or keyword arguments.

Note

The render method is currently exported, but this export may be deprecated in the future.

Mustache.render_from_file — Tuple{AbstractString, Any}

source
render_from_file(filepath, view)
render_from_file(filepath; kwargs...)

Renders a template from filepath and view.

Note

This function simply combines Mustache.render and Mustache.load and may be deprecated in the future.

Mustache.@jmt_str — Tuple{String}

source
jmt"string"

String macro that interpolates values escaped by dollar signs, then parses strings.

Note: very lightly modified from a macro in HypertextLiteral.

Example:

x = 1
toks = jmt"$(2x) by {{:a}}"
toks(; a=2) # "2 by 2"

Mustache.@mt_str — Tuple{Any}

source
mt"string"

String macro to parse tokens from a string. See parse.