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

Download history 3/week @ 2024-07-01 73/week @ 2024-07-29

每月下载 73

MIT 许可证

235KB
4.5K SLoC

Stuart

一个闪电般的快速静态网站生成器。
立即下载 »







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 部分(通过我们稍后将看到的 beginend 函数标记)将插入到页面的头部,而 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支持的唯一脚本有onPreBuildonPostBuild。在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正在运行的 环境。这将是以productiondevelopmentbenchmark之一。

模板语言

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