htmz

Package Version Hex Docs

Quick start

gleam test  # Run the tests
gleam shell # Run an Erlang shell

Installation

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.

Usage

Examples

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()
}

“type=” issue

The “type” is a keyword in gleam, so you can’t use it as a field name. Use “type_” instead.

Input
|> z.type_("text")

“Z” element

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" />

HTMX support

All htmx attributes are supported.

Button
|> z.HxGet("/load-me")
|> z.HxSwap("outerHTML")
|> z.HxTrigger("load")

Alpine.js support

All Alpine.js attributes are supported.

Div
|> z.x_data("{ username: 'calebporzio' }")
|> z.children([
 Text("Username: "),
 Strong
 |> z.x_text("username"),
])

Inserting text

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.

Conditions

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")
Search Document