[][src]Macro hiccup::hiccup

macro_rules! hiccup {
    ($w:expr, ) => { ... };
    ($w:expr, $e:tt) => { ... };
    ($w:expr, $tag:ident {$($key:expr => $value:expr),*}[($($code:block)*) $($inner:tt)*] $($rest:tt)*) => { ... };
    ($w:expr, $tag:ident {$($key:expr => $value:expr),*}[$($inner:tt)*] $($rest:tt)*) => { ... };
    ($w:expr, $tag:ident [($($code:block)*) $($inner:tt)*] $($rest:tt)*) => { ... };
    ($w:expr, $tag:ident {$($key:expr => $value:expr),*} $($rest:tt)*) => { ... };
    ($w:expr, $tag:ident [$($inner:tt)*] $($rest:tt)*) => { ... };
    ($w:expr, $tag:ident [($($code:block)*)] $($rest:tt)*) => { ... };
}

hiccup!:

  • The main objective of this lib is to prevent unclosed html tags. This macro is inspired by Clojures hiccup

Basic usage:

The macro `hiccup! receives a mutable string as the first argument and mutates the string to emit the HTML. The order of the elements is:

  1. tag as the first element.
  2. Optional attribute inside the tag should follow the tag name as {attribute1=>"value1 value2 ... valuen", attr=>"value"}. Also, the attributes should be inside {...} and separate each key value pair by ,. The element should be written as key=>"value", where key is a symbol, followed by an arrow (=>), and then the value as a string "value".
  3. After (Optional) the tag name or the attributes {...} you could include [...] that can have other tags, such as p["text"] or regular string values.
  4. Inside the [...] you also can substitute your string for some simple rust code inside a (...). This can bem something like p[format!("{:?}", 3 + 4)] or div[(x)] where x was defined in the outside.

Differences between Clojure and Rust Hiccup:

  • Clojure: [:a {:href "http://github.com"} "GitHub"]
  • Rust: a{href=>"http://github.com"}["GitHub"]

Syntax with code inside:

  • a{href=>"http://github.com"}[(format!("{:?}", 3 + 5))]
  • p[(x)], where x can be another html or simply a value;

Example

Basic syntax

use hiccup::hiccup;

fn main() {
    let mut html = String::new();

    let _ = hiccup!(&mut html,
        html[
            head[meta{name=>"author", content=>"Julia Naomi"}
                title["Hiccup guide"]]
            body{class=>"amazing hiccup guide"}[
                h1{font=>"bold", color=>"red"}["Hiccup is the best!"]
                p["please lookup clojure's hiccup for better ideas on this macro"]]
        ]);

    assert_eq!(html,"<html><head><meta name=\"author\" content=\"Julia Naomi\"/>\
    <title>Hiccup guide</title></head><body class=\"amazing hiccup guide\">\
    <h1 font=\"bold\" color=\"red\">Hiccup is the best!</h1>\
    <p>please lookup clojure\'s hiccup for better ideas on this macro</p></body></html>");
}

With remote code execution

use hiccup::hiccup;

fn main() {
    let mut html_inner = String::new();
    let mut html_outer = String::new();
    let x = "inner my str";
    let y = "my str2";
    let z = "my str3";

    let _ = hiccup!(&mut html_inner,
        div[
            div{hello=>"inner world"}[(x)]
        ]
    );

    let _ = hiccup!(&mut html_outer,
        html[
            body{class=>"amazing hiccup guide"}[
                p["please lookup clojure's hiccup for better ideas on this macro"]
                div[
                    div{hello=>"world"}[(html_inner)]
                    div[(y.to_owned() + " " + z)]
                    p["bye"]
                ]
            ]
        ]);

    assert_eq!(html_outer,"<html><body class=\"amazing hiccup guide\">\
    <p>please lookup clojure\'s hiccup for better ideas on this macro</p>\
    <div><div hello=\"world\"><div><div hello=\"inner world\">inner my str</div></div></div>\
    <div>my str2 my str3</div><p>bye</p></div></body></html>");
}

FAQs

  1. Is it possible tu use this lib as an XML templating?

Yes, I added a more generic XML case to the tests recently

use hiccup::hiccup;

fn main() {
    let mut out = String::new();

    let _ = hiccup!(&mut out,
        xml{metas=>"I forgot them all", version=>"any version"}[
            family[name{name=>"Rubiechiov", origin=>"Kazakhstan"}]
            members{class=>"close family"}[
                member{age=>"oldest", color=>"yellow"}["some name"]
                member{age=>"mid-age", color=>"yellow"}["some other name"]
                member{age=>"yougest", color=>"brown"}["Julia"]]
        ]);

    assert_eq!(out,"<xml metas=\"I forgot them all\" version=\"any version\"><family>\
    <name name=\"Rubiechiov\" origin=\"Kazakhstan\"/></family><members class=\"close family\">\
    <member age=\"oldest\" color=\"yellow\">some name</member>\
    <member age=\"mid-age\" color=\"yellow\">some other name</member>\
    <member age=\"yougest\" color=\"brown\">Julia</member></members></xml>");
}