Skip to content

Latest commit

 

History

17 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Daizen

Go Reference License

Daizen 是一个 Go 语言的静态站点生成器。编译期模板 + 零拷贝渲染管线 + 增量缓存,设计目标是让全量构建快到不需要增量。

3000 页冷构建     Daizen 0.19s   Hugo 0.98s
3000 页热构建     Daizen 0.10s   Hugo 0.98s(无增量)
40000 页冷构建    Daizen ~2.5s   Hugo 全量困难

以上数据基于相同内容、相同 markdown 引擎(goldmark)、最简模板对比。 完整主题下 4 万页预计 3–4 秒。

特性

  • Goh 模板引擎 — Hero 兼容语法,<%: func %> 编译为原生 Go 函数,运行时零反射零分配
  • 多模板引擎.goh(原生)/ .tmpl / .gohtml / .ejs / .pug
  • 内置分类体系 — 自动生成标签页、分类页、归档页、首页分页
  • SEO 内置 — Atom feed、RSS 2.0、sitemap.xml、robots.txt
  • front matter — YAML --- / TOML +++ / JSON ;;; / 无分隔 JSON
  • permalink 路由 — 全局 :year/:month/:title/ 模板或单篇覆盖
  • 草稿支持source/_drafts 默认跳过,--draft 包含
  • 开发服务器 — 文件监听 + 增量重建 + SSE 热刷新
  • TUI 编辑器 — 浏览/新建文章页面草稿,行编辑器带保存

安装

go install github.com/OblivionOcean/Daizen@latest

快速开始

mkdir my-blog && cd my-blog

# 站点配置
cat > _cfg.yml <<'EOF'
title: My Blog
url: https://example.com
theme: my-theme
source_dir: source
public_dir: public
per_page: 10
EOF

# 创建内容
mkdir -p source/_posts layout themes/my-theme/layout
cat > source/_posts/hello.md <<'EOF'
---
title: Hello World
date: 2025-01-01
tags: [test]
---
Hello, **Daizen**!
EOF

# 构建
daizen g
# 输出在 public/

命令

命令 别名 说明
generate g 构建站点;.goh 变更自动重编译
server s 开发服务器,文件变更自动重建 + SSE 热刷新
edit [file] TUI 编辑器:浏览/新建文章页面草稿
rebuild 强制重新生成布局代码并重编译
reset 清空 .daizen/ 构建产物
cp src dst 复制文件/目录(站点根相对路径)
mv src dst 移动/重命名
info 显示站点信息
route [file] 查询 source → output 路由映射
install <src> i 安装主题包到 .daizen/themes/
uninstall <name> uni 卸载已安装的主题包

配置

_cfg.yml

title: My Blog
subtitle: ''
description: '站点描述'
keywords: keyword1,keyword2
author: Author Name
language: zh-cn
timezone: 'Asia/Shanghai'
url: https://example.com

theme: my-theme          # 对应 themes/<name>/ 目录

source_dir: source       # 内容目录
public_dir: public       # 输出目录
tag_dir: tags            # 标签页输出目录
category_dir: categories
archive_dir: archives
layout_dir: layout       # 站点级自定义布局

per_page: 10             # 分页大小(0 关闭分页)
pagination_dir: page     # 分页路径前缀

workers: 4               # 并发协程数(默认 = CPU 核心数)
# draft: true            # 包含草稿(也可用 --draft 参数)

permalink 路由

permalink: :year/:month/:day/:title/

支持变量::year :month :day :hour :minute :second :title(源文件名去扩展名)。

单篇文章可在 front matter 中覆盖:

permalink: my-custom-path/

结尾 / 自动追加 index.html;无扩展名时追加 .html

主题

目录结构

themes/<name>/
├── _config.yml        # 主题默认配置(站点根 _cfg.theme.yml 可覆盖)
├── layout/
│   ├── root.goh       # 外壳(RegRootLayout)
│   ├── post.goh       # 文章页
│   ├── page.goh       # 独立页面
│   ├── index.goh      # 首页(含分页)
│   ├── tag.goh        # 单标签列表 + 标签总览
│   ├── category.goh   # 分类页(回退到 index)
│   └── *.tmpl|.ejs|.pug  # 其他引擎
└── source/            # 静态资源 → 透传到 public 根

注册优先级:编译期 Go 插件 > 站点 layout/ > themes/<name>/layout/

Goh 模板语法

继承自 Hero,由内嵌的 Goh 生成器编译为原生 Go 函数:

<%: func Post(site *model.SiteInfo, page *model.Page, buf *bytes.Buffer) %>
<h1><%= page.Meta.GetString("title") %></h1>
<% for _, t := range page.Meta.GetList("tags") { %>
    <span class="tag"><%==v t %></span>
<% } %>
<div><%- page.Content %></div>
语法 说明
<%= expr %> HTML 转义输出
<%- expr %> 原样输出
<%==t expr %> 类型化原样输出(b/i/u/f/s/bs/v
<% go code %> Go 代码块
<%: func ... %> 函数定义(最后一个参数必须是 *bytes.Buffer
<%! go code %> 函数外代码(import、全局变量等)
<%~ "parent" %> 继承父模板
<%+ "child" %> 包含子模板
<%@ name { %> <%@ } %> Block 定义与闭合
<%# comment %> 注释

修改 .goh 后下次 daizen g 会自动:解析模板 → 生成 Go 代码 → 重编译二进制 → 以新二进制重新执行当前命令。

数据模型

// 所有引擎统一
page.title       // Meta["title"]
page.path        // 输出相对路径(含 permalink)
page.date        // Meta["date"]
page.tags        // []string
page.categories  // []string
page.layout      // 当前布局名
page.meta.*      // 原始 front matter
page.content     // markdown 渲染后的 HTML
page.rawContent  // 原始正文

site.cfg.*       // 站点配置
site.posts       // []*Page(按日期倒序)
site.pages       // 总页数

body             // 仅 root/base 布局:内部内容

Go 模板使用 {{.Site.Cfg.title}} {{.Page.Meta.title}} 等。

front matter

---
title: 文章标题
date: 2025-01-01T12:00:00+08:00
updated: 2025-06-01
tags: [Go, 性能]
categories: [技术]
author: Author
excerpt: 自定义摘要
headimg: /img/cover.png
permalink: custom-url/     # 覆盖全局 permalink
draft: false
layout: post               # post/page/false(false=不套布局直接输出)
---

插件系统

主题和功能通过本地目录 + Goh 代码生成实现,无需动态加载:

themes/<name>/layout/*.goh  → 解析 → .daizen/gen/*.go → 重编译二进制

安装外部主题包:

daizen install ./my-theme          # 本地目录
daizen install https://github.com/user/theme.git  # git 仓库
daizen uninstall my-theme

安装位置为站点级 .daizen/themes/<name>/,不影响其他项目。

SEO

每次构建自动生成到 public/

文件 格式 内容
atom.xml Atom 1.0 最新 20 篇,含 author/category/content/published
rss.xml RSS 2.0 最新 20 篇,含 dc:creator/category/CDATA
sitemap.xml XML Sitemap 全部页面 URL + lastmod
robots.txt robots.txt Allow all + sitemap 引用

通过 _cfg.yml 设置 "seo": false 关闭。

开发服务器

daizen s        # 默认 http://127.0.0.1:4000
daizen s -p 8080
  • 监听 source/layout/themes/*/layout/themes/*/source/
  • 变更后 600ms 内自动增量重建
  • SSE 热刷新注入每个 HTML 页面,浏览器自动 reload
  • .goh 变更触发重编译(提示重启 server)

项目结构

cmd/                  CLI 入口 + daizen-edit TUI 编辑器
internal/
  router/             路由处理 + permalink
  router/front-matter YAML/TOML/JSON front matter 解析
  gohgen/             内嵌 Goh 模板解析器与代码生成器
plugins/
  templates/          多引擎适配器(Go template / EJS / Pug)
  taxonomy/           标签/分类/归档/首页分页 + SEO 生成
renderer/             两阶段并行渲染管线
markdown/             goldmark + Chroma 语法高亮
cache/                mtime 增量缓存
theme/                主题配置加载与注册
model/                数据模型
utils/                零拷贝工具函数 + sendfile 拷贝

性能

基于 slinso/goTemplateBenchmark 的测试结果:

BenchmarkComplexGoh-16     2304783    535.4 ns/op    0 B/op    0 allocs/op
BenchmarkComplexHero-16    1410391    863.5 ns/op    0 B/op    0 allocs/op
BenchmarkComplexJade-16    1826784    651.8 ns/op    0 B/op    0 allocs/op

Goh 是该基准中最快的模板引擎。

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages