Skip to content

About

以网站为主体的(与hexo等生成式相反),混合型博客生成系统(目标为支持有后端和纯静态博客,目前支持纯静态)

Topics

Resources

Stars

4 stars

Watchers

2 watching

Forks

Repository files navigation

BeautifulBlog

默认文档:中文。English version: README.en.md

BeautifulBlog 是一个静态网站生成器。它与 Hexo 等工具一样,最终产物是可以部署到普通静态文件服务器上的网站文件;关键区别在于,主题不是由生成器套用的页面模板,而是一个由主题作者控制的独立网站程序。

生成器负责提供文章转换结果、索引和生命周期通知。主题自己决定如何读取这些数据、组织页面、实现导航、选择展示方式,以及是否加入浏览器端交互。生成器不规定主题必须有哪种首页、文章页或 URL 结构,只要求主题与约定的数据和钩子接口兼容。

与模板式生成器的区别

模板式生成器 BeautifulBlog
生成器读取主题模板,再把文章填入模板并拼成页面 主题是独立的网站代码,拥有自己的页面结构和运行逻辑
主题主要描述布局、样式和模板语法 主题可以自行实现首页、路由、搜索、目录、推荐和交互
生成器控制文章如何进入页面 生成器提供文章数据及变更通知,主题决定如何使用
主题通常在生成器定义的模板生命周期内工作 主题可包含浏览器端程序;Node 端钩子用于和生成器协作

发布结果仍是静态文件。主题可以用 JavaScript 在浏览器中加载文章或提供交互,但不要求线上运行 BeautifulBlog 的 Node 服务。

工作方式

articles/                  文章源文件
    │
    ├── 格式转换器读取文章和 front matter
    ▼
content/                   标准化文章数据、HTML 内容、附件和 files.json 索引
    │
    ├── 生成器通知当前主题的 hooks
    ▼
sites/<主题名>/             主题源码:浏览器网站程序 + Node 生命周期钩子
    │
    └── 复制到 nowSite/      当前运行主题的副本
                               │
                               └── 生成器内置静态服务器或外部静态托管

生成器的文章转换器负责把 Markdown、TXT、PDF 等输入转为当前约定的中间结果。主题可以使用这些 HTML 和元数据,也可以按自己的组织方式组合它们;生成器不会把文章自动塞进主题的首页或模板。

主题目录包含两类代码:

  • 浏览器端网站:通常由 index.html 和脚本、样式、静态资源组成。它是网站本身,可以独立决定如何呈现 content/ 中的数据。
  • Node 端 hooks:hooks.js 由生成器进程加载,用来接收主题切换、完整生成和文章变更等事件。它不是浏览器脚本,也不会被当作页面模板执行。

集成约定

当前站点主要通过三类约定与生成器协作:

  1. 内容文件:每篇文章生成同路径的 JSON 元数据和 HTML 内容,并可能带有附件目录。元数据包含标题、日期、front matter 自定义字段、内容长度、修改时间和源文章标识。
  2. 文章索引:content/files.json 的 fileList 保存文章元数据 URL、标题、源文章标识和附件目录 URL。主题可用它构建列表,也可选择自己的索引策略。
  3. 生命周期 hooks:主题导出符合 ISiteHooks 的对象。当前实现会在切换主题时调用 beforeUnload 和 loaded;blog generate y 强制重新生成完成后调用 generated;监视到文章新增、修改或删除并重新生成后调用 articleChanged(context, type, dest)。其他重新生成流程目前不一定触发 generated。

主题还可以通过 hooks 导出的 metainfo.articleExtensions 声明自己支持的原始文章扩展名,并实现可选的 interceptArticle(context)。生成器会把 sourcePath、destinationPath、extension、当前配置和全局配置传给它;回调返回 TransformResult 时,主题完全接管该文章,生成器只负责把结果写成标准的 HTML、JSON 和附件目录;回调返回 undefined 时,才回退到默认 transformer。这样主题可以处理生成器原本不认识的格式,也可以决定自己的解析、元数据和输出结构。

init、install、uninstall 虽出现在接口定义中,但当前生成器流程没有完整调用它们;主题不应依赖这些事件。数据文件也尚无独立的 schema 版本号,新增或调整字段时应保留兼容读取,并在后续版本中完善版本化约定。

base_url 是部署路径前缀。主题请求文章、脚本、样式和附件时必须保留该前缀,不能依赖网站部署在域名根目录,也不能写入开发机绝对路径。

目录结构

独立博客目录通常包含:

articles/       文章源文件
content/        生成的文章内容、元数据、附件和索引
config/         base_url、当前主题等配置
sites/          可选主题源码
nowSite/        当前主题运行副本,由工具同步覆盖
assets/         博客级共享资源

默认主题的目录职责、构建方式、数据契约和演进计划见 默认站点构建指南。

快速开始

开发环境使用 Node.js 24.12 或以上版本和 pnpm 10:

pnpm install
pnpm build
pnpm test
pnpm blog -h

从 CLI 创建独立博客目录:

pnpm blog init ./my-blog

进入博客目录后,使用安装好的 blog 命令启动同步服务器:

blog sync 8080

命令会按配置重新生成 content/、同步所选主题到 nowSite/,然后启动静态服务器并监视文章和主题文件。访问地址会在启动日志中输出,路径前缀由 config/<名称>.json 的 base_url 决定。CLI 的完整子命令和参数以 blog -h 为准。

主题开发

主题作者负责网站自身的结构和行为。可以从 sites/default 开始,也可以创建全新的主题目录。常见工作包括:

  • 自行设计首页、文章阅读、导航和 URL 结构。
  • 自行决定文章列表、分类、标签、搜索、归档和推荐如何呈现。
  • 使用约定的内容索引和元数据,或在主题中建立自己的数据层。
  • 在 Node hooks 中响应主题加载、全量生成及单篇文章变更,执行必要的索引刷新或其他副作用。
  • 将主题构建为浏览器可运行的文件,并确保 nowSite/ 副本具备独立服务所需的资源。

主题 TypeScript、钩子签名及默认主题构建方式见 默认站点构建指南。主题不要手动修改 nowSite/,它是工具同步生成的运行副本。

CLI 常用命令

  • blog init <目录>:创建独立博客目录和默认主题。
  • blog generate [y|n] [verbose]:生成文章内容;第一个参数为 y 时强制重新转换。
  • blog changesite [主题名]:切换当前主题。
  • blog sync [端口]:启动静态服务器并监视文章和主题变更。
  • blog refresh:重新生成内容并同步当前主题。
  • blog new <a|c> <相对目录> <名称>:创建文章或子目录。
  • blog config <add|del|use> <参数>:管理配置。

构建、测试与发布

pnpm build
pnpm test
pnpm pack

pnpm build 编译生成器、检查默认主题并打包浏览器入口;pnpm test 在构建后运行测试。pnpm pack 生成 npm 包。独立程序构建命令为 pnpm pkgwin、pnpm pkglinux 和 pnpm pkgall。

当前边界与后续方向

  • 主题是网站程序,不是通用模板;默认主题只是示例实现,不代表生成器要求的页面形态。
  • 当前内置转换器提供通用 HTML 和元数据,但 transformer 插件体系仍在完善。
  • 主题原始文章拦截已支持;主题切换和强制刷新采用非破坏式提交,旧主题不支持某种格式或拦截器失败时会保留已有 HTML、JSON、附件和索引。
  • ISiteHooks 声明的部分安装生命周期目前尚未接入调用流程。
  • 内容索引和元数据格式需要增加 schema 版本,并定义向后兼容策略。
  • README 曾规划 EJS/Hexo 模板兼容;这属于可选适配方向,不应改变主题独立控制网站的核心模式。

About

以网站为主体的(与hexo等生成式相反),混合型博客生成系统(目标为支持有后端和纯静态博客,目前支持纯静态)

Topics

Resources

Stars

4 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages