Create a reusable HTML template
templating.Rdtemplate() is a function factory that captures a template expression and
returns a callable HTML renderer. The expression is evaluated
under the htmltools::withTags() environment, so tag functions such as
div() or p() are available.
Templates may define:
parameters: symbols or named defaults which are used as arguments to the renderer
content injection: if the template uses
..., the renderer passes...to the containing HTML nodes defined in the template.fragments: named subtemplates that can be optionally extracted from the template upon rendering by supplying
fragment = "name". Fragment names are required.
Usage
template(..., .envir = parent.frame())
fragment(name = NULL, ...)Attributes
Attributes with non-leading underscores are
rewritten as hyphenated versions instead.
This means you can write
htmltools::div(data_foo="bar") which is converted to
htmltools::div(data-foo="bar").
An escape hatch exists If you explicitly want
underscores in your attributes.
You may use double underscores, which
will be converted to single underscores
e.g.
htmltools::div(data__foo="bar") which is
converted to htmltools::div(data_foo="bar").
Examples
# Example Fragment Usage
page_main <- template(
{
div(
h1("Dashboard"),
fragment(
p("Welcome back"),
name = "content"
),
small("2026")
)
}
)
page_main(fragment="content")
#> <p>Welcome back</p>
# Template slots
details <- template(name, age, {
nm <- sprintf("Hello, my name is: %s", name)
old <- sprintf("I am %s years old.", age)
div(
p(nm),
p(old)
)
})
details("Jim", 30)
#> <div>
#> <p>Hello, my name is: Jim</p>
#> <p>I am 30 years old.</p>
#> </div>
# Templates and fragments can also be combined
card <- template(
ttl, footer = NULL, {
div(
h2(ttl),
fragment(div("Card body"), name="body"),
if (!is.null(footer)) {
fragment(
div(footer),
name = "footer"
)
}
)
}
)
card("Card Title")
#> <div>
#> <h2>Card Title</h2>
#> <div>Card body</div>
#> </div>
card("Card Title", fragment="body")
#> <div>Card body</div>
card("Card Title", "Footer text", fragment = "footer")
#> <div>Footer text</div>
# Dots (content injection)
layout <- template({
htmltools::tagList(
head(meta(title = "foo")),
body(...)
)
})
layout(htmltools::div("content"))
#> <body>
#> <div>content</div>
#> </body>