Crate hotman

source ·
Expand description

github crates.io docs.rs

html
hot male
hotman.

🥵 Simple HTML generation in pure Rust with no macros 🥵

Usage

Writing HTML with hotman is very similar to writing HTML itself. All the same words are there, only the punctuation is different.

Elements

Html elements are constructed using functions with the same name as the tag.

Examples are head, body, div, and p.

Elements can be converted to strings with the Display trait (and by extension, the ToString::to_string method).

ElementData

The ElementData trait is implemented for any type which adds either attributes or children to an element.

ElementData is also implemented for Options, arrays, Vecs, some iterators, and tuples of ElementDatas up to 20.

The element functions all take an ElementData as their argument, so you can pass tuples for multiple values.

Attributes

Attributes are represented by structs with the same name as the attribute. They implement ElementData.

Examples are Id, Href, Class, and Style.

Events

Individual event handler attributes do not each have their own struct.

Instead, they can be added to elements via the On struct.

On implements ElementData and consists of an Event and a string representing the handler.

Static Example

use hotman::*;

let dom = html((
    Comment("A simple login page"),
    head((
        meta(Charset("utf-8")),
        title("Login"),
        script(Src("/script.js")),
    )),
    body((
        h1("Login"),
        form((
            (Action("/login"), Method("POST")),
            input((
                Type("text"),
                Name("username"),
                Placeholder("Username"),
                On(Change, "validate_username()"),
                Autofocus,
            )),
            input((
                Type("password"),
                Name("password"),
                Placeholder("Password"),
                On(Change, "validate_password()"),
            )),
            input((Type("submit"), Value("Login"))),
        )),
        BR,
        p((
            "Don't have an account? ",
            a((Href("/register"), "Register")),
        )),
    )),
))
.page();

println!("{dom}");

Iteration

A blanket implementation of ElementData for any Iterator would conflict with the implementaiton for tuples.

As a workaround, ElementData is implemented for the Map, FilterMap, and FlatMap iterators.

Because you usually map data to elements anyway, these implementations are usually more than enough.

let number_list = {
    use hotman::*;
    ul((1..=5).map(|i| li(i.to_string())))
};

assert_eq!(number_list.to_string(), "\
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
</ul>");

Scoping

To make writing HTML as short as possible, hotman exports every element, attribute, and event in the root of the crate.

This means that there are many potential name conflicts with surrounding code.

It is recommended to scope use hotman::* to a small block of code:

let page_head = {
    use hotman::*;
    head((title("My Page"), meta((Name("Description"), Content("A page")))))
};

Re-exports

Modules

Structs

Enums

Constants

  • Short alias for br(())

Traits

  • Trait for types of elements
  • A piece of data that can be added to an element

Functions