SiYuan v3.5.2 版本变更详解:从 ISOMonth 模板函数到“最近的文件”配置上限的源码级解读
2026/9/10 16:21:39 网站建设 项目流程

SiYuan v3.5.2 版本变更详解:从 ISOMonth 模板函数到“最近的文件”配置上限的源码级解读

【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan

本篇基于 SiYuan 仓库内 v3.5.2 繁体中文版更新日志 全文展开,完整覆盖该版本的 12 项功能改进、5 项缺陷修复、1 项开发重构与 3 项插件开发者变更;并结合仓库中 模板函数注册表、时间工具库、文件树配置 与 启动配置初始化 等源码,解释每项变更背后的实现机制,帮助读者既了解“这个版本改了什么”,也理解“它是如何实现的”。

版本概述

v3.5.2 更新日志 对该版本的整体描述非常克制:“此版本改進了一些細節”。这类“细节版本”恰恰是理解一款笔记产品工程细节的好入口:其中既有面向模板作者的新函数行为修正(ISOMonth),也有面向自托管用户的安全增强(随机生成 Cookie 金鑰),还有面向插件生态的 API 松绑(快捷键可選、loadData容错)。下文按日志原文的四个板块(改進功能、修復缺陷、開發重構、開發者)逐条解析。

日志中的每一条变更都对应一个上游 issue/PR 编号(16339、16537、16621、16638、16674、16688、16690、16691、16703、16706、16718、16720 等),可按编号在上游仓库检索完整讨论上下文。

功能改进(Enhancement)

v3.5.2 共列出 12 项功能改进,完整清单与逐条说明如下。

1. 解决点击图表块和 PDF 链接导致的白屏问题

点击关系图(graph)块以及 PDF 链接时会出现白屏,属于典型的渲染进程异常场景。此项修复使这两类入口不再触发整页白屏,改善了桌面端/移动端的稳定性。

2. 桌面端导出 PDF 支持不分页

桌面端在将文档导出为 PDF 时新增了“不分页”选项,长文档可以连续输出为单页长卷,适合打印手册、长截图式归档等场景。从源码结构看,导出链路由 导出 API 与 导出模型 承载,PDF 生成能力由 PDF 模块 提供,分页/不分页即通过导出参数在该链路上生效。

3. 改进 HTML 行级元素的剪藏

剪藏网页时,HTML 中的行级(inline)元素此前可能出现截断,本版本改进了对行级元素的剪藏处理,使剪藏内容的完整性更好。剪藏能力对应仓库中的 剪藏模型 与 剪藏 API。

4. 改进双向关联字段的默认填入值

属性视图(AV)中的双向关联字段在自动填入关联文档时,本版本改进了其默认填入值的取值逻辑,使关联字段的行为更符合预期。双向关联字段的底层计算位于 AV 关联模块,字段值处理位于 字段值模块。

5. “移动”支持按文档块 ID 搜索

在“移动”文档操作中,现在可以直接输入文档块 ID 进行搜索定位。块 ID 是 SiYuan 中每篇文档/每个块的全局唯一标识,按 ID 搜索对脚本化、批量移动文档非常实用。该能力依托 文件树 API 与 树节点模型 中的块查询逻辑。

6. 改进集市插件的最低版本要求

插件集市(Bazaar)在安装插件时会校验当前内核版本与插件声明的最低版本要求,本版本改进了该校验逻辑,避免因版本门槛判断不准确导致的误装或误判。集市相关实现位于 集市模块 与 插件安装逻辑。

7. 随机生成 Cookie 金鑰

这是本版本一项重要的安全增强:服务端的加密 Cookie 密钥不再依赖固定或用户可预测的值,而是在首次启动时随机生成并持久化。仓库源码可以直接印证这一机制,启动配置初始化 中:

if cookieKey := readCookieKey(); "" != cookieKey { Conf.CookieKey = cookieKey } else { if "" == Conf.CookieKey { Conf.CookieKey = gulu.Rand.String(16) } writeCookieKey(Conf.CookieKey) }

逻辑是:优先读取独立存储的 Cookie 密钥文件;若不存在,则检查配置项cookieKey(见 Conf.CookieKey 定义)是否为空,为空时随机生成 16 位字符串密钥并写回密钥文件。随后 HTTP 服务启动 时以model.Conf.CookieKey作为 Cookie 加密密钥传入server.Serve。对自托管(/api/http服务、Docker 部署)用户而言,这意味着密钥在每次全新部署时都不同,减少了凭据被猜测/复用的风险。

8. 改进点击大纲和打开块引用时的定位

点击左侧大纲标题跳转、或打开块引用(block reference)定位目标块时,滚动定位精度得到改进,解决了此前定位偏移、滚动不到位的问题。大纲数据来自 大纲 API,块引用渲染位于 虚拟引用模块 与 块引用查询。

9. 改进超级块的编辑与撤销

“超级块”指同时选中并编辑多个块的场景(如合并编辑、块级多选)。本版本改进了超级块编辑过程中的撤销(undo)行为,避免出现撤销后内容残留或撤销栈错乱。撤销栈的实现位于 Undo 日志模块。

10. 支持鸿蒙端在离线时使用

HarmonyOS 端现在支持在无网络环境下继续使用(本地内核模式),与移动端离线能力对齐。鸿蒙内核入口见 harmony/kernel.go,其中会直接以本地方式启动内核服务。

11. 改进模板函数ISOMonth

模板系统内置了ISOWeekISOYearISOMonthISOWeekDate等 ISO 8601 时间函数,统一注册在 模板函数表:

ret["ISOWeek"] = util.ISOWeek ret["ISOYear"] = util.ISOYear ret["ISOMonth"] = util.ISOMonth ret["ISOWeekDate"] = util.ISOWeekDate

本版本重点修正了ISOMonth的语义:它返回的不是日期所在的自然月,而是“该日期所在 ISO 8601 周的周四所在的月份”。这一语义在 工具实现 中非常清晰:

// ISOMonth returns the month in which the Thursday of the ISO 8601 week of date occurs. func ISOMonth(date time.Time) int { isoYear, isoWeek := date.ISOWeek() // 1. 找到该 ISO 年份的 1 月 4 日(它必然属于第 1 周) jan4 := time.Date(isoYear, time.January, 4, 0, 0, 0, 0, date.Location()) // 2. 找到第 1 周的周四 daysToMonday := (int(jan4.Weekday()) + 6) % 7 mondayOfWeek1 := jan4.AddDate(0, 0, -daysToMonday) thursdayOfWeek1 := mondayOfWeek1.AddDate(0, 0, 3) // 3. 计算目标周的周四 targetThursday := thursdayOfWeek1.AddDate(0, 0, (isoWeek-1)*7) // 4. 返回该周四所在的自然月份 return int(targetThursday.Month()) }

算法思路可以拆解为四步:以 ISO 年份的 1 月 4 日为锚点(它必然落在 ISO 第 1 周),回溯到第 1 周的周一再加 3 天得到第 1 周的周四,然后按(isoWeek-1) * 7天平移到目标周的周四,最后取其所在自然月。之所以以“周四”为周的代表日,是因为 ISO 8601 规定第 1 周包含该年的第一个周四,周四所在月份即该周归属的月份。这个函数对按“周”做统计归档的模板(例如周报模板中“本周属于几月”)非常关键,修正后周边日期(12 月底、1 月初)的归类结果将与ISOWeek/ISOYear的口径保持一致。

12. 支持配置“最近的文件”列出的最大数量

文件树中的“最近的文件”面板现在可以配置其列出的最大条数。对应配置项定义在 FileTree 配置结构:

RecentDocsMaxListCount int `json:"recentDocsMaxListCount"` // 最近的文档最大列出数量

并配有取值边界常量 32 ~ 256:

const ( MinFileTreeRecentDocsListCount = 32 MaxFileTreeRecentDocsListCount = 256 )

保存设置 API 在用户提交配置时执行同样的夹取逻辑:超过上限取上限、低于下限取下限,启动时读取配置 也会再夹取一次,保证落盘值始终合法。该面板的数据由 getRecentDocs 接口 提供,路由注册于 POST /api/storage/getRecentDocs;发布访问控制场景下还会经过FilterRecentDocsByPublishAccess过滤。对自托管多设备用户而言,这条上限既控制面板渲染压力,也让“最近文件”列表长度变得可控。

缺陷修复(Bugfix)

本版本共修复 5 个缺陷,完整清单与说明如下。

  1. 无法在多个工作区之间切换发布服务:同一内核运行多个工作区时,发布(Publish)服务无法正确切换目标工作区。修复后发布服务可跟随当前工作区切换。发布访问控制实现位于 publish_access。
  2. 只读模式下无法跳转搜索结果:在只读模式(如发布站点/只读实例)下点击搜索结果无法跳转到对应块,本版本修复了该导航问题。只读模式的全局开关即conf.go初始化中的Conf.ReadOnly
  3. 属性值未进行转义:属性字段值在展示/导出路径中未做转义处理,可能导致内容被当作标记解析或注入意外的 HTML 语义。转义修复保证了属性值按纯文本语义呈现。
  4. updateBlockAPI 遇到空指针错误:插件/脚本调用updateBlock更新块内容时,在特定入参(空内容或块不存在等边界条件)下会触发空指针异常。修复后该 API 在边界条件下返回错误而非崩溃,属于插件 API 的健壮性修复。
  5. “优化排版”中任务清单嵌套提示块异常:开启“优化排版”后,任务清单内嵌套的 Callout(提示块)会触发渲染异常,本版本修复了该嵌套场景。任务清单模型位于 todo.go。

开发重构(Refactor)

  • 升级至 Electron v39.2.7:桌面端主框架升级到 Electron v39.2.7。需要注意版本口径:更新日志记录的是 v3.5.2 发布时的 Electron 基线,而当前仓库 app/package.json 中声明的electron版本已演进至42.6.1,说明 Electron 基线在后续版本中持续滚动升级。桌面端的窗口、安全策略等实现见 electron/main.js 与 electron/window.js。

插件开发者相关变更(Development)

这部分变更直接面向插件作者,是 v3.5.2 对插件生态最实质的一批改进。

  1. 即使loadData执行失败,插件也应继续运行:此前插件的loadData(读取插件数据)若抛错,整个插件初始化会中断。调整后loadData失败不再阻断插件后续生命周期,提升了插件容错性。插件运行时的加载与 RPC 入口见 plugin 模块 与 api_plugin.go。
  2. 使插件命令和工具栏的快捷键可选:插件注册的命令(command)与工具栏(toolbar)此前要求必须提供快捷键(hotkey),本版本将其改为可选项——插件可以只注册可点选/可调用的命令而不绑定按键,降低了插件开发门槛。命令与快捷键注册链路涉及 api_rpc.go 及 快捷键模型。
  3. 改进插件数据存储方法的错误处理与安全性:插件侧数据读写 API(对应 api_storage.go)加强了错误返回与输入校验,使插件数据存取在异常路径下行为更可预期、更安全。

相关源码与文档路径速查

主题仓库相对路径
v3.5.2 更新日志(繁中/简中/英)v3.5.2_zh_CHT.md、v3.5.2_zh_CN.md、v3.5.2.md
模板函数注册(含ISOMonthkernel/filesys/template.go
ISOMonth等 ISO 时间函数实现kernel/util/time.go
“最近的文件”数量上限配置kernel/conf/filetree.go
最近文件 APIkernel/api/storage.go、kernel/api/router.go
Cookie 密钥随机生成kernel/model/conf.go → kernel/model/conf.go
插件加载 / 数据存储 APIkernel/plugin/plugin.go、kernel/plugin/api_storage.go
桌面端主进程app/electron/main.js、app/package.json

小结

v3.5.2 是一个典型的“细节版本”:功能侧新增了ISOMonth语义修正、recentDocsMaxListCount可配置、随机 Cookie 密钥等可被源码直接验证的改动;修复侧覆盖多工作区发布切换、只读搜索跳转、属性转义、updateBlock空指针等稳定性问题;开发者侧则通过loadData容错、快捷键可选、存储 API 加固降低了插件开发门槛。对自托管用户和插件作者而言,阅读 更新日志原文 并按上表路径回看对应源码,是理解 SiYuan 版本演进机制的一个完整样本。

【免费下载链接】siyuanAn open-source, privacy-first, self-hosted knowledge workspace where humans and AI agents work together 开源、隐私优先、自托管的知识工作空间,让人与智能体在此协作项目地址: https://gitcode.com/GitHub_Trending/si/siyuan

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询