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日 |
在 模板引擎 中排名 38
每月下载 73 次
235KB
4.5K SLoC
Stuart 是一个非常快速且灵活的静态网站生成器,每页构建时间低至 0.1ms。它用 Rust 编写,旨在比其他 SSG 更易于使用,同时在基准测试中胜出。Stuart 的简单但强大的模板系统允许您为网站定义复杂的逻辑,从 Markdown、JSON 文件以及模板文件中提取数据,然后再将其渲染为静态 HTML。对于更复杂的项目,您可以使用任何与核心构建系统集成并使用 Rust 或 JavaScript 编写的自定义构建脚本和插件来增强 Stuart。
注意: 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"
项目结构
A 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 数据
使用HTML页面中的import
模板函数,JSON数据文件也可以作为Stuart网站的源数据。该函数将JSON文件导入为变量。
静态文件
静态文件应放在static
目录中,在构建结束时与构建内容合并。文件名冲突会导致构建失败。
构建脚本
构建脚本应放在scripts
目录中。目前,Stuart支持的唯一脚本有onPreBuild
和onPostBuild
。在Windows上,这些脚本应具有.bat
扩展名,而在Linux上,它们应具有.sh
扩展名或根本没有扩展名。这些脚本分别在构建前后运行。
如果项目配置中启用了save_metadata
,则onPostBuild
脚本可以访问metadata.json
文件中的构建元数据。
如果预构建脚本需要在输出目录中创建文件,它应该在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) |
insert |
将一个部分插入到模板中,仅在 root.html 中使用。 |
insert("section_name") |
import |
将 JSON 文件导入为变量。 | import($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() |
excerpt |
从字符串创建摘录。 | excerpt($post.content, 100) |
timetoread |
计算阅读字符串所需的时间(以分钟为单位)。 | timetoread($post.content) |
插件
Stuart 支持动态加载的插件,这些插件是提供额外功能的 Rust 库。插件依赖关系在先前提到的 stuart.toml
文件中指定。可以在模板内部通过在函数名前加上插件名称来调用插件函数,例如
{{ my_plugin::my_function() }}
如果函数名不与其他函数冲突,则可以省略插件名称。如果冲突,内置函数优先于插件函数,但插件函数的顺序是未定义的。因此,请不要这样做。
本地插件 API
原生插件使用核心包中的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。
依赖项
~11–38MB
~749K SLoC