#html-templating #html #template #render-template #zero #web

bin+lib hatter

积极疯狂,无依赖的 HTML 模板语言

8 个版本

0.1.4 2020年10月23日
0.1.3 2020年10月22日
0.0.3 2020年10月8日
0.0.2 2020年9月27日
0.0.1 2020年5月28日

#134 in 模板引擎

28 每月下载量
用于 3 crates

MIT/Apache

140KB
3.5K SLoC

Hatter

The Mad Hatter discussing Hatter

对于先前接触过 Hatter 的学生来说,教授他们良好的编程几乎是不可能的:作为潜在程序员,他们的思想被扭曲得无法恢复。

-– Edsger W. Dijkstra (据说)

Hatter 是一种小型的空白敏感型模板语言,内置 HTML 支持。其 HTML 功能和语法是对 Imba 的廉价仿制,但 Hatter 生成的是原始静态 HTML - 看不到任何 JavaScript。

Hatter 可以用来生成静态网站或以传统方式在 Web 应用程序中渲染服务器端内容 - 要么使用 Vial,要么使用你选择的 Rust Web 框架。

如果你感到冒险或像帽子一样疯狂,可以使用独立的二进制文件将模板转换为 HTML 文件,或者将零依赖的 Rust 库包含在你的 (web/cli/?) 应用程序中。


你好,Hatter

以下是一些 Hatter 的基本示例以及它生成的 HTML

<!-- Hatter -->
<#main> Hi there!

<!-- Generated HTML -->
<div id='main'>Hi there!</div>
<span.big.bold> Welcome!

<span class='big bold'>Welcome!</span>
<.links> for link in nav-links
  <a href={link.href}> link.text

<div class='links'>
  <a href='/link1'>First Link</a>
  <a href='/link2'>2nd Link</a>
  <a href='/link3'>Final Link</a>
</div>
<form GET="/search">
  <input@query:text placeholder="Search..." /> <input:submit />

<form method='GET' action='/search'>
  <input name='query' type='text' placeholder='Search...' />
  <input type='submit' />
</form>

功能

  • 根据缩进来自动关闭 HTML 标签和代码块
    • <h1> Welcome, <i> Rob 变为 <h1> Welcome, <i> Rob </i></h1>
  • idclasstypename 属性的简写
    • <div#id>
    • <div.class1.class2>
    • <input@form-field-name>
    • <input:text>
  • 常规属性的动态值
    • <div 页码={page.id}>
  • 条件设置属性或启用缩写
    • <div.已记录-登录=已记录-登录?>
    • <div 数据映射=is-map?>
  • 字符串插值
    • <span.问候语> "嘿,{name}。2 + 2 等于 {2 + 2}"
  • 缩写插值
    • <span#page-{page.id} .-{page.类型}>page.标题
  • 隐式 div
    • <#main>变为<div id='main'>
  • 隐式闭合标签
    • <i>delicious</>变为<i>delicious</i>
  • 易于使用的内联 JavaScript
    • <li> <a onclick=(alert("Oink!"))> "🐷"
  • 基本类型
    • bool,int,float,string,list,map, fn
  • 遍历 listmap
    • <ul> forpage登录pagesdo <li id=page-{page.id}>page.name
    • fork,v登录some-mapdo <td>k</> <td>v
  • if/else 语句
    • iflogged_in?then<h2>欢迎回来!
  • 使用 :== 进行错误检查赋值
    • name := 'Bob' 如果 name 已经设置,则会出错。
    • name = 'Bob' 如果 name 没有设置,则会出错。
  • 调用 Rust 中定义的函数
    • <div.name>-大写(name)
  • 使用严格参数数量和隐式返回值定义自己的 Hatter 函数
    • defgreet(name) do print("嘿,{name}!")
    • greet("Lydia") 打印 Hey there, Lydia!
  • 定义自己的 Hatter 操作符
    • def++(a,b) do concat(-大写(a), ' ',-大写(b))
    • "one" ++ "two" 返回 ONE TWO
  • 闭包和函数字面量
    • adder := fn(x) fn(y) x + y 然后 add1 := adder(1)
    • add1(200) 返回 201
  • 使用关键字参数调用函数
    • defgreet(标题,name) do print("嗨,{title}。{name}!")
    • greet(name: "Marley", title: "Dr") 打印 Hiya, Dr. Marley!
  • do 关键字用于一行块
    • if 2 > 1 do print("显然")
    • forx登录listdo print(x)
  • then 关键字用于一行 if 语句
    • if 2 > 1thenprint("是的!") else if 2 < 1thenprint("不可能。")
  • Hatter 将添加一个 <!DOCTYPE> 并将所有内容包裹在 <html> 中,如果您的模板中的第一个标签是 <head>

入门指南

使用 Hatter 有两种方式

1. 在您的 Rust 应用程序中

Hatter 可以(主要)作为模板语言在您的 Rust 应用程序中使用。

只需将 Hatter 添加到 Cargo.toml

[dependencies]
hatter = "0.1"

然后创建一个 hatter::Env,它代表您模板的最高级别 Hatter 范围,以设置变量并渲染模板

use hatter::{Args, Env, Value};

let mut env = Env::new();
env.set("name", "Bobby Boucher");
env.set("age", 31);
env.render(r#"
<p> <b>Name:</> name
<p> <b>Age:</> age
"#)

您还可以在 Rust 中编写函数,并将它们提供给您的 HTML 模板

use hatter::prelude::*;

fn quote(args: Args) -> Result<Value> {
  let file = std::fs::read_to_string("quotes.txt")?;
  let list_of_quotes: Vec<_> = file.split('\n').collect();
  let line = match args.need_number(0)? as usize {
    n if n > list_of_quotes.len() => 0,
    n => n,
  };

  Value::from(list_of_quotes[line]).ok()
}

fn main() {
    let mut env = Env::new();
    env.set("quote", quote);
    println!("{}", env.render("<div> quote(1)").unwrap());
}

有关更多信息,请参阅 API 文档

2. 作为独立的可执行文件

Hatter 可以用作常规的命令行程序,将 .hat 文件转换为 HTML。

只需使用 cargo 安装它

cargo install hatter

然后将其指向任何 .hat 文件

$ cat test.hat
<b.test> "Testing 1 2 3 {2 + 2}"

$ hatter test.hat
<b class='test'>Testing 1 2 3 4 </b>

您还可以使用 readline 驱动的 REPL 安装 Hatter

cargo install hatter --features repl

要启动它,无需任何参数启动 hatter

$ hatter
Hatter v0.0.1 REPL
>> 1 + 2
3

TODO

  • HTML化的错误页面
  • 在运行时错误中显示源文本中的错误位置

未来特性

  • 定义您自己的标签
    • def<项目(项目)> do <li.项目数据-id={项目.id}>项目.text.
  • 函数的可选类型检查
  • 标准库
  • VSCode 扩展
  • luacheck-style 工具
  • LSPc

许可证

Hatter 可以根据您的意愿选择以下任何一个许可证

Imba 使用 MIT 许可证

依赖项

~0–740KB
~11K SLoC