4 个版本
0.1.3 | 2022年8月22日 |
---|---|
0.1.2 | 2022年8月21日 |
0.1.1 | 2022年8月6日 |
0.1.0 | 2022年8月6日 |
在 网页开发 中排名 1935
125KB
3K SLoC
mini-builder-rs
静态网站生成器。
编程语言使用函数来避免重写类似的逻辑。HTML 没有这样的功能。此包提供了一种可以插入到 HTML(或任何)文件中的简单语言,以便以编程方式生成新文件。
例如,考虑以下 HTML
<section>
<a href="page 1" class="selected">Page1</a>
<a href="page 2" class="">Page2</a>
<a href="page 3" class="">Page3</a>
</section>
如果没有静态网站生成器,这个 HTML 片段就必须复制并粘贴到每个页面,并对 a
标签将具有 selected
类的微小更改。然而,使用静态网站生成器,这个片段可以存储在文件中,例如 navigation.html
,然后在每个页面上重复使用。例如
navigation.html
<section>
<a href="page 1" class="{{ if page == 'page 1' ? 'selected' : ''}}">Page1</a>
<a href="page 2" class="{{ if page == 'page 2' ? 'selected' : ''}}">Page2</a>
<a href="page 3" class="{{ if page == 'page 3' ? 'selected' : ''}}">Page3</a>
</section>
page1.html
...
{{@ navigation(page = 'page 1')}}
...
示例
有关一些代码示例,请查看 examples
目录。
构建器
Builder
处理
mini_builder_rs::builder::Builder::new(
// sources - the source for the pages that will be generated
Some("./examples/example_site/sources".into()),
// templates - the partial files that can be referenced
// from sources or other templates
Some("./examples/example_site/templates".into()),
// generated - where the transformed sources will be placed
Some("./examples/example_site/generated".into()),
// variables - a file containing global variables and their values
Some("./examples/example_site/variables".into()),
// see mini_builder_rs::builder::BuilderOptions
Default::default(),
)
.unwrap()
// variable that will be available for every source and template
// (unless shadowed)
.add_variable("title", Value::text("Website Title"))
.add_variable(
"files",
Value::List(DATA.iter().map(|x| Value::text(x.0)).collect::<Vec<_>>()),
)
// functions that can be called from every source and template
.add_function("get_file_size", Box::new(get_file_size) as _)
// watch for changes in the sources and templates directories,
// updating the generated directory live
.watch()
.unwrap();
...
fn get_file_size(values: &[Value]) -> Value {
if let Some(Value::Text(name)) = values.get(0) {
for (file_name, file_size) in DATA {
if file_name == name {
return Value::Number(*file_size);
}
}
}
Value::None
}
资源和模板
资源对应于输出文件。模板是用于生成文本的资源或模板。例如,如果资源是 page_1.html
、page_2.html
,模板是 navigation.html
和 footer.html
,则网站完成后的输出将是仅 page_1.html
和 page_2.html
的展开版本。
模板使用以下语法调用:@ template(key1 = value1, ...)
。
模板的名称可以是显式地给定作为字符串,也可以是在从文件加载时相对于模板目录的文件路径(忽略扩展名)(例如,模板 template/sub_dir1/temp1.html
的名称将是 sub_dir1/tmp1
)。
变量和函数
使用以下枚举定义值
pub enum Value {
Number(f32),
Bool(bool),
Text(String),
List(Vec<Value>),
None,
}
函数通过类型定义:Box<dyn Fn(&[Value]) -> Value + 'static>
。
指令
指令是一段具有以下模式的代码:{{...}}
,它为普通文件添加逻辑。如 if
语句这样的控制流指令使用略有不同的模式:{{# ...}}
。指令内部使用的语言可以通过以下几个例子总结:
- 表达式
<!-- if the variables `a` and `b` are defined, they will be added and returned
-->
<p> a + b = {{ a + b }} </p>
- 如果语句
{{# if page == 'page 1' }}
<!-- if the variable `page` exists and equals to 'page 1' this section will
be evaluated -->
...
{{# elif page == 'page 2'}}
<!-- elif is short for else if -->
...
{{# else }}
....
{{#}}
- for 循环
<!-- the for each loop will be evaluated if the variable `files` exists and is
a list -->
{{# for file in files}}
<h2>{{ file }}</h2>
{{#}}
- 三元运算符
{# if a != None && b != None}}
<p>a is{{ a > b ? 'greater than : a < b ? 'smaller than' : 'equals to'}} b</p>
{{# else}}
<p>a or b are none</p>
{{#}}
- 模板
<!-- Templates are not control flow, they are expressions and therefore can be
with other expressions. if no variables are passed to a template then both the
syntaxes `@ template` and `@ template()` are valid. -->
{{ use_pretty_header ? @ pretty_header : @ normal_header}}
<!-- call the `footer` template with a single variable called
`use_pretty_footer` whose value equals to the variable `use_pretty_header`
value's -->
{{@ footer(use_pretty_footer = use_pretty_header)}}
依赖关系
~3–12MB
~111K SLoC