一个用 Swift 编写的静态站点生成器,允许您为项目提供自己的元数据类型。 Saga 使用可扩展的读取器、渲染器和写入器系统,支持诸如 Atom 订阅、分页和强类型 HTML 模板等功能。
Saga 的主要目标是灵活性;特别是拥有多组项目,每组项目都有自己(强类型)的元数据的能力。 这是大多数其他生成器不支持的功能。 例如,您可以拥有一个网站,其中在 /blog/
下有博客文章,每篇文章都有一个或多个标签。 您将为每个标签(/blog/[tag]/
)创建一个页面,并且您还希望按年份进行归档(/blog/[year]/
)。 当然,所有内容都必须分页,每页显示 20 篇文章。 您想要所有文章的 RSS 订阅,以及每个标签的订阅。 到目前为止,这没什么特别的,基本上任何静态站点生成器都可以做到这一点。
但是,如果您还想向您的网站添加一个项目组合呢? 每个项目都有自己的 markdown 文件,其中包含与您的文章不同的元数据,例如指向 App Store 的链接和一组屏幕截图。 您想在 /portfolio/
上显示此内容,也许您还想为您的 iOS、Android 和 Web 项目创建单独的页面。 或者,假设您想在您的网站上显示电影评论:您将评论存储在单独的 markdown 文件中,每个评论一个文件。 评论再次具有不同的元数据,例如发行年份、主要演员、流派、评分和主要图像。 您想在 /movies/
上显示这些评论,您想要每个年份、每个流派和每个演员的页面。 或者食谱怎么样,您可以将菜系、课程类型和复杂度存储为元数据?
很少有静态站点生成器能够处理如此多样化的内容,尤其是当您在一个网站中处理多种类型的内容时。 Saga 确实提供了所有这些灵活性,甚至更多。
由于 Saga 侧重于代码而不是配置,因此无需处理隐藏的行为,无需覆盖默认值,无需学习神奇的约定,无需理解数百个配置选项的文档。 一切都是从上到下强类型的,您明确地告诉 Saga 如何构建您的网站。
func renderPage(context: ItemRenderingContext<EmptyMetadata>) -> Node {
html(lang: "en-US") {
body {
div(id: "content") {
h1 { context.item.title }
Node.raw(context.item.body)
}
}
}
}
@main
struct Run {
static func main() async throws {
try await Saga(input: "content", output: "deploy")
// All files will be parsed to html.
.register(
readers: [.parsleyMarkdownReader()],
writers: [.itemWriter(swim(renderPage))]
)
// Run the step we registered above
.run()
// All the remaining files that were not parsed from markdown, so for example images, raw html files and css,
// are copied as-is to the output folder.
.staticFiles()
}
}
该示例使用 Swim 创建类型安全的 HTML。
当然,Saga 可以做的不仅仅是按原样渲染一个 markdown 文件目录。 它还可以处理 markdown 文件中包含的自定义元数据 - 甚至适用于不同类型页面的多种元数据类型。
请参阅文档以获取安装说明、系统要求、基本入门信息以及更高级内容的指南。
可以从 Xcode(Product > Build Documentation)或 loopwerk.github.io/Saga/documentation/saga/ 访问文档。
您需要使用 markdown 阅读器将 markdown 文件解析为 HTML,并且您需要使用一个渲染器,该渲染器提供对 HTML 模板的支持。 Saga 提供了多种选择
您的网站是使用 Saga 构建的吗? 发送一个 pull request 将其添加到此列表中!