2 个不稳定版本

0.1.0 2024 年 1 月 20 日
0.0.0 2024 年 1 月 14 日

#597Rust 模式

MIT 许可证

15KB
101

htmxpress

用于快速从 Rust 结构体生成 htmx 的进程宏。

属性

参考

element

在指定的元素内包含字段内容到最终的 HTML 中。

每个字段/结构体只允许一个元素属性。

当应用于结构体时,所有内部的元素都将被指定的元素包装。

没有此属性的字段在生成 HTML 时将被忽略。随后,与 HTML 元素相关的任何其他属性也将被忽略。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("p")]
  foo: String
}
<div><p>foo</p></div>

attrs

指定元素的 HTML 属性。对于常用静态属性很有用。

属性指定为 ident = "value" 对。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
#[attrs(class = "container")]
struct El {
  #[element("p")]
  #[attrs(class = "inner", id = "foo")]
  foo: String
}
<div class="container"><p class="inner" id="foo">foo</p></div>

attr

指定元素的单一属性。

当属性必须动态创建或其键不能写成有效的 Rust 标识符时很有用。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
#[attr("funky-attr" = "value")]
struct El {
  #[element("p")]
  #[attr("dynamic" = "{}", param)]
  foo: String,
  param: usize,
}
<div funky-attr="value"><p dynamic="param">foo</p></div>

format

使用提供的格式字符串格式化元素的内容。

仅在字段上有效。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("p")]
  #[format("Hi, I'm {}")]
  foo: String
}
<div><p>Hi, I'm foo</p></div>

map

在写入 HTML 之前使用表达式映射此字段的值。

此属性仅适用于 HTML 生成。任何带有此注解的字段在用于其他属性的格式字符串中仍将使用其原始值。

有效语法是 variable => { /* do stuff with variable */ }

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("p")]
  #[attr("id" = "{}", foo)]
  #[map(var => var.is_empty())]
  #[format("Empty: {}")]
  foo: String
}

let el = El { foo: "foo".to_string() };
let html = r#"<div><p id="foo">Empty: false</p></div>"#;

assert_eq!(html, el.to_htmx());
<div><p id="foo">Empty: false</p></div>

default

仅适用于 Option 和未注解 map 的字段。

通常情况下,在HTML生成过程中标记为element且值为NoneOption将被完全忽略,不会创建任何DOM对象。此属性确保即使字段值为None,元素也会被创建并包含指定内容。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("p")]
  #[default("foo")]
  foo: Option<String>,

  #[element("p")]
  bar: Option<String>
}

let el = El { foo: None, bar: None };
let html = r#"<div><p>foo</p></div>"#;

assert_eq!(html, el.to_htmx())
<div><p>foo</p></div>

before/after

在元素的内容前后插入/附加字符串。

特别适用于在父元素内部插入元素,尤其是在处理列表时。

list一起使用时,它会在第一个/最后一个元素前后插入指定的字符串。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("section")]
  #[before("<h1>Win a million dollars</h1>")]
  #[after("<button>Do it</button>")]
  foo: String
}

let el = El { foo: "You are the chosen one".to_string() };
let html = r#"<div><section><h1>Win a million dollars</h1>You are the chosen one<button>Do it</button></section></div>"#;

assert_eq!(html, el.to_htmx())
<div>
  <section>
    <h1>Win a million dollars</h1>
    You are the chosen one
    <button>Do it</button>
  </section>
</div>

nest

适用于任何实现了HtmxElement结构的字段。在当前结构的上下文中调用底层实现。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
struct El {
  #[element("section")]
  #[nest]
  foo: Qux
}

#[derive(Element)]
struct Qux {
  #[element("p")]
  qux: &'static str,
}

let el = El { foo: Qux { qux: "qux" } };
let html = r#"<div><section><p>qux</p></section></div>"#;

assert_eq!(html, el.to_htmx())
<div>
  <section><p>qux</p></section>
</div>

list [(嵌套)]

适用于列表集合。适用于任何实现了Display接口的迭代器。

为列表中的每个项目创建指定的元素,并使用项目的值作为其内容。

当作为list(nest)使用时,对列表中的每个项目调用to_htmx(),并将其写入最终HTML中。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("ul")]
struct El {
  #[element("li")]
  #[list]
  foo: Vec<&'static str>,

  #[list(nest)]
  #[element("li")]
  bar: Vec<Qux>,
}

#[derive(Element)]
struct Qux {
  #[element("p")]
  qux: &'static str,
}

let el = El { foo: vec!["foo1", "foo2"], bar: vec![Qux { qux: "qux" }] };
let html = r#"<ul><li>foo1</li><li>foo2</li><li><p>qux</p></li></ul>"#;

assert_eq!(html, el.to_htmx())
<ul>
  <li>foo1</li>
  <li>foo2</li>
  <li>
    <p>qux</p>
  </li>
</ul>

hx, hx_method

hx_*属性对应于htmx中可用的AJAX方法。它们还支持格式字符串,即可以使用问题结构的字段动态生成。

hx基本上与attrs相同,不同之处在于它将hx添加到每个键的前面。

需要动态值时,请使用attr

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
#[hx_get("/foo/{}", path)]
#[hx("swap" = "innerHtml")]
#[attr("hx-target" = "#{}", id)]
struct El {
  path: &'static str,

  #[element("p")]
  #[attr("id" = "{}", id)]
  #[format("Meaning of life: {}")]
  id: usize,
}

let el = El { id: 420, path: "bar" };
let html = r##"<div hx-get="/foo/bar" hx-target="#420" hx-swap="innerHtml"><p id="420">Meaning of life: 420</p></div>"##;

assert_eq!(html, el.to_htmx())
<div hx-get="/foo/bar" hx-swap="innerHtml" hx-target="#420">
  <p id="420">Meaning of life: 420</p>
</div>

urlencode

在需要编码URL参数时使用。

示例

use htmxpress::{Element, HtmxElement};

#[derive(Element)]
#[element("div")]
#[hx_get("/foo/{}", path)]
#[urlencode]
struct El {
  path: &'static str,
}

let el = El { path: "my bar" };
let html = r##"<div hx-get="/foo/my%20bar"></div>"##;

assert_eq!(html, el.to_htmx())
<div hx-get="/foo/my%20bar"></div>

更多示例

#[derive(Debug, htmxpress::Element)]
#[element("div")]
#[hx_post("/somewhere/{}", some_property)]
struct Parent {
    some_property: String,

    #[element("p")]
    #[hx_get("/somewhere/else")]
    #[format("I am a p! {}")]
    my_p: String,

    #[nest]
    child: Child,
}

#[derive(Debug, htmxpress::Element)]
#[element("div")]
#[attrs(id = "child", class = "child-class")]
#[hx_get("/elsewhere")]
struct Child {
    #[element("p")]
    #[attr("id" = "keepit{}", meaning_of_life)]
    #[format("Always keep it {}")]
    meaning_of_life: usize,
}
<div hx-post="/somewhere/something">
  <p hx-get="/somewhere/else">I am a p! Hello World!</p>
  <div hx-get="/elsewhere" id="child" class="child-class">
    <p id="keepit69">Always keep it 69</p>
  </div>
</div>

待办事项列表

  • 基本HTML
  • Ajax属性
  • ez列表集合的属性
  • [] 响应特性
  • [] 响应特性的hx头部

依赖关系

~1–1.4MB
~29K SLoC