ZotFlow 1.7.0
这个版本按照 Zotero 自己的同步模型重写了同步。在 Obsidian 和 Zotero 两边做的修改 现在会逐字段合并,因此真正变成冲突的情况少了很多。剩下的冲突会告诉你 ZotFlow 为 什么停下来、两边各改了什么,以及每个选项会带来什么结果。除此之外,1.7.0 让笔记 编辑更安全,让 Source Note 跟上标注和子条目的变化,加入了可自定义的显示标题,并把 模板测试器做成了完整的编辑工具。
一次性数据库升级
首次启动时,ZotFlow 会把本地数据库升级到新格式。升级自动完成,并会保留尚未同步 的修改。保险起见,建议在更新前先用 1.6.x 同步一次(推荐,但不是必须)。升级 后旧版 ZotFlow 无法再打开这个数据库;如果要退回 1.6.x,需要清空本地缓存并重新 同步。
亮点
- 同步会合并,而不是互相覆盖。 在 Obsidian 里改了一条笔记的标签、在 Zotero 里改了它的正文,两边的修改都会保留。任意两个不同字段都是如此,两边各自添加的 标签也会合并在一起。
- Activity Center 新增 Conflicts 标签页。 每个冲突都会显示逐词差异、Keep Local 和 Accept Remote 各自的结果预览,以及一个解释 ZotFlow 为什么需要你来 决定的「?」按钮。
- 输入的内容不会再丢。 Source Note 和笔记编辑器中的修改会在任何重新渲染或 同步之前写入。如果你正在编辑的笔记已在 Zotero 中被删除,ZotFlow 会提示你把文字 另存为一条新笔记。
- 标注或子条目变化时,Source Note 也会刷新,不再只看父条目本身是否变化。
- 多设备更安全。 文库数据较旧的设备,不会再用旧数据覆盖另一台设备渲染出的 较新 Source Note。
- 可自定义显示标题,用于文库树和条目搜索。
- 模板测试器升级: 变量面板、带行号位置的错误提示,并可直接保存到设置或模板 文件。
- 大型文库同步快了很多,首次同步也不会再让手机内存耗尽。
- Activity Center 和模板测试器加入了手机和平板布局。
重写的同步引擎
ZotFlow 的同步现在采用和 Zotero 相同的做法:记住两边最后一次一致的版本,再分别 拿两边与它比较(三方合并)。
- 逐字段合并。 不同字段的修改会自动合并,标签和分类按集合合并。一边把笔记 移入回收站、另一边编辑了它,两项修改都会保留。
- 只在真正冲突时询问。 只有同一个字段在两边被改成了不同的值,或者一边删除、 另一边编辑时,ZotFlow 才会停下来询问,绝不会悄悄覆盖任何一边。
- 冲突在你决定前保持不变。 编辑一条已经处于冲突中的笔记或标注,不会再把你的 修改直接推上去覆盖 Zotero 中的版本。
- 网络不稳时也可靠。 如果某次上传的响应丢失,下次同步时 ZotFlow 会判断这次 写入是否已到达服务器,不会重复发送,也不会丢失。遇到限流和服务器错误会退避后 重试。
- 大型文库。 下载的数据按批次随到随存,首次同步中断后可以从中断处继续。在我们 的测试中,15,000 个对象的文库首次同步从约 44 秒降到约 6 秒;带有数千条标注的 PDF 从几分钟缩短到几秒。
- 同一文库同时只跑一个同步。 某个文库正在同步时再点「全部同步」,两次同步不会 再叠在一起运行。
同步相关修复
- iPad 和 iPhone: 之前上传时没有带上 Zotero 的版本校验,导致 iOS 上的修改 可能覆盖 Zotero 中更新的修改,在 Zotero 中删除的条目也可能被重新创建。现在 iOS 上所有请求的请求头都能正确发送。
- 群组权限: 在 API Key 页面把某个群组设为 None 或 Read Only 时,现在会 像 Zotero 一样正确回退到该 Key 的默认群组权限。
- 两边都移入回收站的笔记不会再显示为有修改。
- 因父条目已不存在而被 Zotero 拒绝的写入,以前会在每次同步时悄悄重试;现在会显示 为一个可以处理的冲突。
Conflicts 标签页
冲突从 Sync 标签页移到了独立的标签页。
- 每个冲突会显示摘要、一张字段表(相对上次同步值的 git 风格逐词/逐行差异,笔记和 评论按 Markdown 显示),以及每个选项的结果。
- Accept Remote 现在只对冲突的字段采用 Zotero 的值。 你其他不重叠的修改会被 保留并上传。如果想用某一边整体替换整个条目,请使用 Keep Local (all fields) 或 Accept Remote (all fields)(「Overwrite all fields with the selected side」)。
- 在 Zotero 中被删除、但下面还有本地修改的条目会显示为一项,受影响的笔记和标注 以树状列出。处理这一项会一并处理整组。
- 暂时无法使用的选项(例如还没取到 Zotero 版本时的 Accept Remote)会被禁用并 显示原因。缺失的 Zotero 版本会在下次同步时重新获取。
- Sync 标签页现在按文库显示待上传(↑)、待下载(↓)的修改数量和冲突数量。
- 在手机上,冲突列表占满屏幕,每个冲突全屏打开,Resolve 按钮始终可见。在平板 和窄窗口中,字段表会变成每个字段一张卡片。
- 条目类型使用 Zotero 的显示名称。
更安全的笔记编辑
- 在 Source Note 可编辑区域(Zotero 笔记、标注评论)和笔记编辑器中的输入会先进入 队列,一停下来就写入。Source Note 重新渲染或同步之前,会先写入尚未保存的修改, 因此不会再覆盖你刚输入的文字。输入后立刻关闭编辑器,也不会再丢掉最后的修改。
- 从命令或 Activity Center 发起的每次同步,都会先保存打开的编辑器中尚未写入的 内容,因此不会上传比屏幕上更旧的版本。
- 笔记已在 Zotero 中删除: 如果你编辑的笔记已在 Zotero 中被删除,ZotFlow 会 显示它的标题、父条目和开头几行,并提供 Save as new note。如果原条目仍然存在, 文字会保存到同一条目下,否则保存为独立笔记,之后你可以在新笔记上继续编辑。笔记 编辑器和 Source Note 现在使用同一个提示。
- 保存内容没有变化的文字时,不会再把笔记标记为待上传。
Source Note
- 子条目变化会触发刷新。 标注、附件或子笔记变化时 Zotero 不会提升父条目的
版本号,所以以前除非强制更新,ZotFlow 会跳过这些笔记。现在 Source Note 会记录
整个条目的
item-tree指纹,下面任何变化都会被识别。1.7.0 之前写入的笔记会被 视为过期一次,并在下次更新时刷新。 - 多设备安全。 Source Note 还会记录
library-version。如果你的仓库在多台设备 间同步,尚未跟上 Zotero 的设备会跳过较新的笔记,不再用旧数据重写它。强制更新仍会 重写。 - 固定的 frontmatter 顺序。 ZotFlow 自己的字段现在总是排在最前面,顺序固定
(
zotflow-locked、zotero-key、library-id、item-version、item-tree、library-version),你的模板字段按模板中的顺序跟在后面。已有笔记会在下次渲染时 调整顺序。 - 长标题不会再出错。 笔记路径的每一段最多 200 字节,并且只在完整字符之间截断
(不会切开汉字或 emoji),长标题不会再因
ENAMETOOLONG失败。 - 只为顶层条目创建 Source Note。 指向标注的
zotero://select链接现在会在其 附件中打开该标注,子附件会在阅读器中打开,独立笔记会作为笔记打开。ZotFlow 不会 再为笔记、标注或子附件创建 Source Note,从搜索中打开独立笔记时也不会再提示 「No attachments found」。 - frontmatter 模板渲染为空时,不会再导致整条笔记失败。
可自定义显示标题
设置 → General → Item Display → Display Title Template 用来设置条目在文库树和
条目搜索中的标题,可使用与引用模板相同的 item. 变量。例如:
{{ item.creatorSummary }} ({{ item.year }}) {{ item.title }}
- 留空则使用 Zotero 标题。某个条目的模板渲染失败或结果为空时,该条目回退为它的 Zotero 标题。
- 按标题排序时使用显示标题。搜索会同时匹配显示标题和 Zotero 标题。
- 附件默认保留文件名,除非你的模板专门处理附件(判断
item.itemType == "attachment")。附件还提供item.filename、item.contentType和item.linkMode。 - 附件旁边的文件类型标签现在根据内容类型显示,没有扩展名的名称不会再整个被当成 标签;独立附件也重新显示文件图标。
模板
所有 Zotero 字段,使用正确的名称
- 模板现在可以访问 Zotero schema 中的所有字段。条目没有的字段会以空值存在,
{% if %}、default等过滤器会把它当作不存在。 - 基础字段按 Zotero 的方式解析:书籍章节的
publicationTitle取自bookTitle, 专利的date取自issueDate,案例的title取自caseName。以前这些值都是 空的,案例、法规和邮件在文库树和搜索中也没有标题。 item.creators现在包含完整的作者信息(creatorType、名和姓),item.creatorSummary提供 Zotero 自己的作者摘要(如「Smith and Jones」 「Smith et al.」)。- 笔记路径模板也支持
item.前缀,例如{{ item.title }},和其他模板保持一致。
模板测试器(Activity Center → Template)
- 变量面板: 列出模板在所选条目或文件上能用到的每个变量及其当前值,点击变量
即可插入到光标处。缺失的值会显示为
undefined、null或"",因为模板对它们 的处理不同。没有元素的数组也会显示结构 (attachments[0].annotations[0].text等)。 - 能定位的错误: 渲染失败会显示阶段、错误信息和位置,点击位置会选中对应行;
frontmatter 出错时会显示它生成的 YAML。未知过滤器(例如拼错的
| titel)在测试 器中会报错,实际渲染时仍会原样放行。 - 提示说明仅看输出看不出来的情况:使用了内置默认模板、某个必需的 frontmatter 字段无法由模板设置、某个值为了文件名被清理过等。
- 保存到实际使用的位置。 渲染无误的模板可以保存到对应的设置(引用、笔记路径 和显示标题模板),或保存到 Source Note 模板文件(如果还没有,会创建文件并设置 好路径)。保存对话框会说明是新建还是覆盖文件。如果输出已过期(上次渲染后你更换 了条目、文件或标注),需要重新渲染后才能保存。
- 新增 Item Display Title 上下文;阅读视图中 Source Note 的 frontmatter 会显示 为属性表格。
- 输入不带
.md的模板路径时,现在读取和保存的是实际渲染所用的同一个文件。 - 在手机上,编辑器和输出面板有固定高度并在内部滚动,Save 和 Render 按钮保持可见。
搜索、文库树和阅读器
- 按 Enter 直接选中第一个结果。 分组标签(「Best Match」「Recent Viewed」
「TYPE」等)不再是可选中的行,在条目搜索、条目选择器和
@@引用中,Enter 都能 立即生效。 - 结果始终对应最后一次输入。 快速输入(例如
type:jo)时,较慢的过期搜索 不会再替换当前的建议列表。 - 在窄屏上,搜索结果中的分类标签会换行并以「…」截断,作者和年份保持可读。
- 在笔记中输入时,文库树只更新变化的条目,不再每隔几秒重建整棵树。
- 阅读器: 通过前进/后退、恢复布局或在同一标签页中打开链接重新打开阅读器时, 不会再卡在「Loading…」。
- 标签编辑器打开时会自动聚焦输入框。
- 所有 ZotFlow 对话框使用统一的标题样式。
其他变化
- 新安装时,渲染出的图片和手写标注默认保存在
Source/Images,而不是仓库根目录。 已有设置保持不变。