gleam test # Run the tests
gleam shell # Run an Erlang shell
If available on Hex this package can be added to your Gleam project:
gleam add htmz
Its documentation can be found at https://hexdocs.pm/htmz.
import htmz.{Html, Title, Head, Body, Div} as z
import gleam/io
pub fn main() {
let html =
Html
|> z.child(
Body
|> z.child(
Div
|> z.text("Hello World"),
),
)
html
|> z.to_string()
|> io.debug()
}
fn nav(inner: Htmz) -> Htmz {
Z(".admins")
|> z.children([
Header
|> z.children([
H2
|> z.text("Administratorzy"),
Menu
|> z.class("sub-menu")
|> z.hx_target("#admins-main")
|> z.hx_push_url("true")
|> z.hx_indicator("#indicator")
|> z.hx_sync("closest menu:replace")
|> z.children([
Li
|> z.child(
Button
|> z.hx_get("/admin/admins")
|> z.text("Lista"),
),
Li
|> z.child(
Button
|> z.hx_get("/admin/admins/new")
|> z.text("Dodaj"),
),
]),
]),
Z("article#admins-main")
|> z.child(inner),
])
}
pub fn main() {
let el =
Html
|> z.children([
Head
|> z.children([
Title
|> z.text("Hello World"),
Meta
|> z.charset("utf-8"),
]),
Body
|> z.children([
Menu
|> z.children([
Li
|> z.child(
A
|> z.href("/about")
|> z.text("About"),
),
Li
|> z.child(
A
|> z.href("/contact")
|> z.text("Contact"),
),
]),
Main
|> z.children([
H1
|> z.text("Hello World"),
]),
]),
])
el
|> z.to_string()
|> io.debug()
}
The "type" is a keyword in gleam, so you can't use it as a field name. Use "type_" instead.
Input
|> z.type_("text")
You can use "Z" element to create any element using css selector notation
Z("sl-button")
|> z.attr("variant", "success")
|> z.label("Click me")
Z(".foo#bar[baz=qux]")
// <div class="foo" id="bar" baz="qux"></div>
Z("i.fa.fa-user")
// <i class="fa fa-user"></i>
Z("input#password-input.form-control[type=password][name=password]")
// <input id="name-input" class="form-control" type="text" placeholder="Name" />
All htmx attributes are supported.
Button
|> z.HxGet("/load-me")
|> z.HxSwap("outerHTML")
|> z.HxTrigger("load")
All Alpine.js attributes are supported.
Div
|> z.x_data("{ username: 'calebporzio' }")
|> z.children([
Text("Username: "),
Strong
|> z.x_text("username"),
])
Text is just a Text node but it has a value parameter. You can insert text nodes like this:
Div |> z.child(Text("Hello World"))
However, since this is a common operation, there is a text(el: Htmz, value: String)
helper function:
Div |> z.text("Hello World")
The z.text()
does exactly the same thing as the previous example.
Using case
you can conditionally render elements:
Div
|> z.children([
H3
|> z.text("Title"),
case maybe_user {
Ok(user) -> z.text(user.name)
Error(_) -> z.text("No user")
}
])
Sometimes it's required to not insert anything. In this case, there is a special node: Nothing
Div
|> z.children([
H3 |> z.text("Title"),
case user
Ok(user) -> z.text(user.name)
Error(_) -> Nothing
}
])
For conditionally inserting attributes follow this pattern:
Div
|> case is_active {
True -> z.class(_, "active")
False -> z.nothing(_)
}
|> z.text("Hello World")