12个版本
0.3.1 | 2024年1月25日 |
---|---|
0.3.0 | 2024年1月24日 |
0.2.7 | 2023年12月31日 |
0.2.5 | 2023年7月15日 |
0.1.1 | 2022年9月10日 |
#449 in 模板引擎
用于 stuart
135KB
2.5K SLoC
Stuart是一款非常快速且灵活的静态网站生成器,每页构建时间低至0.1毫秒。它使用Rust编写,旨在比其他SSGs更易于使用,同时在基准测试中击败它们。Stuart简单而强大的模板系统允许您定义站点复杂的逻辑,从Markdown和JSON文件以及模板文件中获取数据,然后再将其渲染为静态HTML。对于更复杂的项目,您可以使用任何语言的定制构建脚本来增强Stuart,这些脚本与核心构建系统集成,以及使用Rust或JavaScript的定制插件。
注意: Stuart是一个非常新的项目,因此功能和文档仍在添加中。目前,文档仅限于本README。
目录
入门
安装
Stuart提供Windows和Linux的预构建二进制文件。您可以从发布页面下载最新版本。或者,您可以使用Rust的包管理器Cargo从头开始构建代码。为此,克隆仓库并运行cargo build --release
。默认情况下禁用了JavaScript插件的支持,要启用它,请启用js
功能。
Stuart需要安装Git才能使许多功能正常工作。
创建项目
您可以通过运行以下命令创建一个项目:stuart new <项目-名称>
。这将创建一个具有指定名称的新目录,并用基本的项目模板填充它。默认情况下,Stuart 还会在项目目录中初始化一个 Git 仓库,因此为了避免这种行为,您可以使用 --no-git
标志。
构建项目
您可以通过在项目目录中运行 stuart build
命令来构建项目。这将把项目构建到 dist
目录中。
要启动开发服务器,当文件发生变化时,它会自动重新构建项目并在您的浏览器中重新加载,请运行 stuart dev
。这将启动服务器在 https://127.0.0.1:6904。
配置
在 stuart.toml
文件中,您可以在 [settings]
节中设置项目的配置选项。以下是一些可用的选项:
名称 | 描述 | 默认值 |
---|---|---|
strip_extensions |
是否通过创建包含 index.html 文件的文件夹来删除 HTML 文件扩展名 |
true |
save_data_files |
是否将 JSON 数据文件保存到输出目录 | false |
save_metadata |
是否输出有关构建的元数据,用于与构建脚本集成 | false |
您可以在 [dependencies]
节中使用类似于 Cargo 的语法声明插件依赖项,例如
[dependencies]
my_plugin = "/path/to/plugin.so"
my_other_plugin = "/path/to/cargo/project/"
my_git_plugin = "https://github.com/username/plugin"
my_remote_plugin = "https://example.com/plugin.so"
Stuart 将自动检测插件是否需要从 Git 仓库克隆,以及是否需要编译。如果插件需要编译,Stuart 需要安装 Rust 工具链。
您可以使用分号分隔插件源来指定回退,例如
my_plugin = "/lib/plugin.so;https://example.com/plugin.so"
项目结构
一个 Stuart 项目包含多个文件夹,每个文件夹都有特定的用途。此外,一些文件名也有特殊的意义。所有内容都应该放在 content
目录中,因为这是唯一一个会被构建系统处理的目录。
根模板
根模板是一个 HTML 模板文件,称为 root.html
,它为其目录和子目录中的所有其他页面提供基础。将使用与正在渲染的页面最具体的根模板。
它是一个普通的 HTML 文件,可以包含模板标签(我们将在后面讨论),但必须至少包含非常重要的 insert
函数。该函数接受一个参数,即节的名字。节是 Stuart 知道在哪里将内容插入根模板的方式。这可以通过一个例子来说明。
root.html
:
<html>
<head>
{{ insert("head") }}
</head>
<body>
{{ insert("body") }}
</body>
</html>
在这个虚构的例子中,网站的每一页都将渲染到这个模板中。每个页面的 head
部分(通过我们稍后将要看到的 begin
和 end
函数标记)将插入到页面的头部,而 body
将插入到主体中。这允许您为网站定义一个共同的布局,或者为网站的一部分定义布局,并将内容插入其中。
需要注意的是,节是必需的:在根模板中定义的每个节都必须出现在使用它渲染的每个页面上。
可以渲染到这个模板的页面如下
index.html
:
{{ begin("head") }}
<title>Stuart</title>
{{ end("head") }}
{{ begin("body") }}
<h1>Stuart</h1>
<p>A blazingly-fast static site generator.</p>
{{ end("body") }}
HTML和Markdown页面
HTML 页面是普通的 HTML 文件,可以包含模板标签。它们定义了要渲染到根模板中的节。
Markdown页面是Markdown文件,以包含文件元数据的frontmatter开头,然后是页面内容。这些文件被转换成HTML,通过md.html
模板通过$self
变量渲染,然后将这些内容渲染到根模板中。用例子说明会更清晰。
my_page.md
:
---
title: "My Page"
author: "William Henderson"
---
# My Page
Markdown content...
md.html
:
{{ begin("head") }}
<title>{{ $self.title }}</title>
{{ end("head") }}
{{ begin("body") }}
<h1>{{ $self.title }}</h1>
<p>By {{ $self.author }}</p>
{{ $self.content }}
{{ end("body") }}
root.html
如上。
JSON数据
JSON数据文件也可以作为Stuart网站的源数据使用,通过在HTML页面中使用import
模板函数,将JSON文件作为变量导入。
静态文件
静态文件应放置在static
目录中,该目录将在构建结束时与构建内容合并。文件名冲突将导致构建失败。
构建脚本
构建脚本应放置在scripts
目录中。目前,Stuart支持的唯一脚本有onPreBuild
和onPostBuild
。在Windows上,它们应该有.bat
扩展名,在Linux上,它们应该有.sh
扩展名或没有扩展名。这些脚本分别在构建前后运行。
onPostBuild
脚本可以访问metadata.json
文件中关于构建的元数据,如果项目配置中启用了save_metadata
。
如果预构建脚本想在输出目录中创建文件,它应该在temp
目录中这样做,Stuart将在构建结束时将其合并到输出目录中。这是为了避免与构建系统的冲突,因为直接写入输出目录可能会导致意外的行为。
为构建脚本设置了某些环境变量,以提供有关构建的信息。这些是
名称 | 描述 |
---|---|
STUART_MANIFEST_PATH |
stuart.toml 清单文件的完整路径。 |
STUART_MANIFEST_DIR |
包含stuart.toml 清单文件的目录的完整路径。 |
STUART_TEMP_DIR |
在预构建脚本执行期间应放置文件的temp 目录的完整路径。 |
STUART_OUT_DIR |
输出目录的完整路径。 |
STUART_ENV |
Stuart运行的环境。这将要么是production ,development ,要么是benchmark 。 |
模板语言
Stuart模板语言由两个主要部分组成:变量和函数。变量用于将数据插入模板,函数允许更复杂的行为,如迭代和选择。
所有模板标签都包含在双大括号中。变量以美元符号为前缀。
变量
基本变量可以按以下方式插入到模板中
{{ $variable }}
所有变量都是JSON值,因此可以使用点符号访问对象值
{{ $variable.property }}
可以在模板中使用$env
变量访问环境变量,例如,要获取STUART_ENV
环境变量的值,您将使用{{ $env.STUART_ENV }}
。
函数
使用以下语法调用函数
{{ function_name(arg1, arg2, positional_arg="value", ...) }}
Stuart目前支持以下函数
名称 | 描述 | 示例 |
---|---|---|
begin |
开始一个部分。 | begin("section_name") |
end |
结束一个部分或另一个函数。 | end("section_name") , end(function_name) |
插入 |
将一个部分插入到模板中,仅在 root.html 中使用。 |
插入("section_name") |
导入 |
将 JSON 文件作为变量导入。 | 导入($data, "data.json") |
for |
遍历 JSON 数组或 markdown 文件夹。循环通过 end(for) 结束。 |
for($tag, "tags.json") , for($post, "posts/", skip=3, limit=3, order="desc", sortby="date") , for($item, $array) |
dateformat |
使用 chrono 格式字符串格式化日期。日期输入可以是任何类型的格式化日期或时间戳。 | dateformat($date, "%Y-%m-%d") |
if[eq,ne,gt,ge,lt,le] |
执行两个值之间的比较。块通过 end(if[eq,ne,...]) 结束。 |
ifeq($a, $b) , ifge($age, 18) |
ifdefined |
检查一个变量是否已定义。块通过 end(ifdefined) 结束。 |
ifdefined($variable) , ifdefined($variable.property) |
else |
为条件语句开始 else 块。 | else() |
摘录 |
从字符串创建摘录。 | 摘录($post.内容, 100) |
timetoread |
计算阅读字符串所需的时间(以分钟为单位)。 | timetoread($post.内容) |
插件
Stuart 支持动态加载的插件,这些插件是提供额外功能的 Rust 库。插件依赖项在前面描述的 stuart.toml
文件中指定。可以通过在函数名称前加上插件名称来在模板内部调用插件函数,例如
{{ my_plugin::my_function() }}
如果函数名称不与另一个函数冲突,则可以省略插件名称。如果冲突,则内置函数优先于插件函数,但插件函数的顺序是未定义的。因此,请避免这样做。
原生插件API
原生插件使用核心crate中的define_plugin!
宏定义。它们可以向Stuart添加函数,这些函数的实现方式与内置函数完全相同,还可以添加新文件类型的解析器。请参考内置函数以获取函数实现的示例,并参考图像优化插件源代码以了解如何使用新文件类型的解析器。调用宏的示例如下
declare_plugin! {
name: "my_plugin",
version: "1.0.0",
functions: [
SomeFunctionParser,
AnotherFunctionParser
],
parsers: [
MyParser
]
}
您必须将Cargo项目配置为编译为cdylib
库,如下所示(在Cargo.toml
中)
[lib]
crate-type = ["cdylib"]
项目还必须将stuart_core
作为依赖项,以便使用define_plugin!
宏和Stuart插件类型。您可以禁用默认功能以避免编译不必要的依赖项,如下所示
[dependencies]
stuart_core = { version = "*", default-features = false }
JavaScript插件API
当使用js
功能编译时,Stuart还可以使用V8加载用JavaScript编写的插件。这些插件只能向Stuart添加函数。插件只是一个导出包含插件元数据的默认对象的JavaScript模块,类似于Rust中的declare_plugin!
宏
export default {
name: "my_plugin",
version: "1.0.0",
functions: [
{
name: "add",
fn: (a, b) => a + b
}
]
}
当作为参数传递时,Stuart变量将自动转换为JavaScript对象,但对其的更改不会自动传播回Rust端。为此,您可以使用STUART
全局对象来访问插件API。
const self = STUART.get("self");
STUART.set("my_var", `Title: ${self.title}`);
有关更复杂JavaScript插件的示例,请参阅stuart-math,它使用MathJax来渲染LaTeX。
依赖项
~0.8–1.8MB
~35K SLoC