资讯详情

Tolaria 自定义视图:用 .yml 文件 + 客户端过滤引擎实现可复用的笔记过滤列表

发布时间:2026/9/16 23:26:51

500+
企业客户服务经验
120+
行业领域内容覆盖
3000+
原创页面设计沉淀
98%
客户满意度

Tolaria 自定义视图:用 .yml 文件 + 客户端过滤引擎实现可复用的笔记过滤列表

Tolaria 自定义视图用 .yml 文件 客户端过滤引擎实现可复用的笔记过滤列表【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria本篇基于 Tolaria 的架构决策记录 ADR-0040 展开。你将了解到Tolaria 如何把用户保存的过滤列表如 Active Projects、This Weeks Events落地为仓库内可直接编辑的.yml文件过滤条件树AND/OR 分组 10 种操作符如何在 Rust 后端定义并在前端对已加载的VaultEntry[]做客户端求值以及字段解析、wikilink 匹配、相对日期表达式和排序持久化背后的完整实现细节。背景与决策为什么选择独立 .yml 文件ADR-0040 要解决的问题很明确用户希望把经过过滤的笔记列表保存为侧边栏里的具名条目并且这些视图需要满足三个约束跨会话持久化重启后还在通过 git 同步在多台设备间保持一致支持任意 frontmatter 条件不只是内置字段。当时评估了三个方案方案结论理由SQLite views 表否决查询快但无法通过 git 便携且偏离文件优先的数据模型特殊.md文件的 frontmatter否决把非笔记概念塞进笔记格式过度重载独立.yml文件最终选择采纳可移植git 同步、可手工或 UI 编辑、与笔记内容天然分离这与 Tolaria 文件即数据源见 ADR-0002的整体取向一致视图不是数据库记录而是 vault 里真实存在的文件。文件位置与存储格式按 ADR 的决策自定义视图存储为 vault 根目录下.laputa/views/中的.yml文件。每个文件定义一个具名视图包含过滤条件、可选的 icon/color以及排序偏好。ADR 给出的标准格式是name: Active Projects icon: rocket color: blue sort: modified:desc filters: all: - field: type op: equals value: Project - field: status op: not_equals value: done仓库里的演示 vault 恰好包含一个可直接对照的真实示例 demo-vault-v2/views/active-projects.ymlname: Active Projects icon: rocket color: blue sort: modified:desc filters: all: - field: type op: equals value: Project从源码结构看当前实现的磁盘位置是 vault 根下的views/目录而 ADR 中的.laputa/views/是旧路径——view_migration.rs 中的migrate_views会在每次扫描视图时把遗留目录.laputa/views里的.yml文件迁移到views/并在旧目录清空后删除它。也就是说老 vault 无需手动迁移升级后自动完成搬家。ViewDefinition 结构体与全部字段后端对视图文件的完整定义在 views.rs 的ViewDefinition中比 ADR 示例多出两个字段pub struct ViewDefinition { pub name: String, #[serde(default)] pub icon: OptionString, #[serde(default)] pub color: OptionString, #[serde(default, skip_serializing_if Option::is_none)] pub order: Optioni64, #[serde(default)] pub sort: OptionString, #[serde(default, rename listPropertiesDisplay, skip_serializing_if Vec::is_empty)] pub list_properties_display: VecString, pub filters: FilterGroup, }name必填侧边栏显示的视图名icon/color可选外观定制复用与笔记类型相同的 icon/color 控件参考 site/reference/view-filters.mdorder可选整数视图在侧边栏 VIEWS 分区的排序权重sort可选字符串列表排序偏好如modified:desclistPropertiesDisplay可选字符串数组序列化为该 camelCase 键列表视图额外展示的属性列filters必填过滤条件树见下节。order字段的实际作用在compare_views中体现views.rs先按order升序缺省视为i64::MAX再按文件名做稳定兜底保证侧边栏里视图顺序确定且用户拖拽排序可持久化。过滤引擎AND/OR 条件树ADR 定义的核心是过滤器是一棵 AND/OR 分组all/any套条件的树每个条件由field、op操作符和可选的value组成。语法层面FilterGroup / FilterNodeFilterGroup的序列化实现views.rs保证 YAML 中分组只允许写成all或any两种键之一filters: all: # 所有子条件都必须命中AND - field: type op: equals value: Project - any: # 嵌套 OR 分组任意深度 - field: status op: equals value: active - field: status op: equals value: in-progress反序列化时FilterNode的Deserialize实现views.rs采用先试分组、再试条件的策略如果一个 mapping 含有all或any键就解析为FilterGroup否则按FilterCondition解析。这就让嵌套分组与平铺条件在同一列表里自由混排而不需要额外的类型标签。FilterCondition结构views.rs除了field/op/value还有一个regex: bool开关默认false不写入文件时省略——这是 ADR 之后新增的正则能力官方参考文档 site/reference/view-filters.md 也提示正则过滤器面向高级用户建议先在小视图上测试。操作符全集与求值语义FilterOp枚举views.rs即 ADR 列出的 10 个操作符equals、not_equals、contains、not_contains、any_of、none_of、is_empty、is_not_empty、before、after。源码中的求值语义值得逐条确认equals大小写不敏感比较且两边都缺值时视为命中(None, None) true——这对字段缺失的记录与value省略的组合很关键contains小写化后的子串包含any_of/none_ofvalue被解析为字符串数组标量或列表皆可字段值等于其中任意一项即命中is_empty字段缺省或空串都算空before/after走日期时间戳比较见下文相对日期表达式正则模式regex: true仅对equals/not_equals/contains/not_contains生效匹配时大小写不敏感模式编译失败的条件直接判为不命中而不是报错保证一个坏过滤器不会击穿整个视图。字段解析内置字段、frontmatter 属性、关系ADR 描述的解析链是内置字段映射到VaultEntry结构体字段未知字段回落到entry.properties再回落entry.relationships。源码 resolve_condition_field 给出了精确版本fn resolve_condition_fielda(field: str, entry: a VaultEntry) - ConditionFielda { match field { type | isA ConditionField::Scalar(entry.is_a.clone()), status ConditionField::Scalar(entry.status.clone()), title ConditionField::Scalar(Some(entry.title.clone())), body ConditionField::Scalar(Some(entry.snippet.clone())), _ resolve_dynamic_condition_field(field, entry), } }内置字段比 ADR 列举的还多isA是type的别名body映射到笔记摘要布尔字段archived、favorite走专门分支views.rsequals的期望值缺省按true处理is_empty/is_not_empty则取布尔值的否定/本身其余字段先查entry.propertiesfrontmatter 属性JSON 标量数组会被展开成字符串数组见 view_value_conversions.rs再查entry.relationships两者都没有才返回空标量数组属性与关系字段各有专门的求值路径数组属性的equals要求恰好一个元素且等于目标contains/any_of则是成员匹配关系字段的比较基于 wikilink 归一化见下一节。Wikilink 值的 stem 匹配ADR 特别指出[[target|Alias]]形式的 wikilink 值按 stem 匹配剥掉方括号和|后的别名。view_relationships.rs 中的RelationshipLink精确实现了这一规则先trim再依次剥离[[前缀与]]后缀遇到|时取左侧为 stem最后统一小写作为比较键。这意味着在过滤器条件里写target、[[target]]或[[target|任意别名]]都能命中同一关系——手写.yml时这是非常实用的容错能力。相对日期表达式before/after的值解析在 view_date_filters.rs 中按顺序尝试四种格式YYYY-MM-DD按 UTC 零点YYYY-MM-DDTHH:MM:SSRFC 3339 带时区时间戳相对表达式today/yesterday/tomorrow以及数量 day|week|month|year ago与in 数量 unit两种形态数量支持数字 1~12 和英文单词one、two…twelve、a/an/one均视为 1复数s可省略。参考时间取Utc::now()字段值与目标值都成功解析后按毫秒时间戳比较。单测view_date_filters.rs验证了10 days ago、one week ago的换算。由此可以写出本周活动这类常青视图filters: all: - field: eventDate op: before value: 7 days ago后端架构YAML 解析、CRUD 与三个 Tauri 命令ADR 的 Architecture 一节指出 Rust 后端承担三件事serde_yaml解析、过滤求值、文件 CRUD并暴露list_views、save_view_cmd、delete_view_cmd三个 Tauri 命令。对应实现扫描scan_views 先触发遗留目录迁移再遍历views/下每个文件解析失败的文件只记录 warning 并跳过read_view_file单个坏文件不会导致整个视图列表不可用保存save_view 强制文件名以.yml结尾自动create_dir_all建目录序列化为 YAML 后写入——这就是 ADR Consequences 里首次保存时目录自动创建的出处删除delete_view 对文件不存在返回Ok(())删除是幂等的命令层view_cmds.rs 中三个#[tauri::command]全部通过with_boundary/with_view_file校验 vault 路径与视图文件名的边界后才落盘防止越界写入。命令的往返行为有专门的 Rust 测试覆盖view_cmds.rs空库list_views为空 → 保存 → 列表出现 → 删除 → 列表回到空以及删除不存在文件视为成功。过滤求值本身另有测试文件 view_tests.rs 覆盖各操作符组合。需要说明的是ADR 中提到的.laputa/views/经由HIDDEN_DIRS排除于 vault 扫描之外。当前扫描器在 mod.rs 中维护HIDDEN_DIRS: [str] [.git, .laputa, .DS_Store]并且以.开头的目录名一律不扫——迁移后的views/目录虽不在隐藏名单中但.yml扩展本就不符合笔记文件扩展名规则两者互不干扰。前端架构客户端求值为主路径ADR 明确了一个重要的架构取舍UI 的过滤求值发生在前端直接对已经加载进内存的VaultEntry[]数组做客户端过滤Rust 侧的evaluate_viewviews.rs保留给 MCP/CLI 场景不是主 UI 路径。前端的对应实现在 src/utils/viewFilters.ts与 Rust 侧同构的条件树匹配逻辑配套测试 viewFilters.test.ts、viewFilters.relativeDates.test.ts、viewFilters.arrayProperties.test.ts 分别覆盖基础匹配、相对日期和数组属性。这样设计的好处是视图切换不需要任何 IPC 往返列表响应即时Rust 侧evaluate_view则让外部 AI 工具MCP能用同一套语义查询 vault见 ADR-0011 的 MCP 集成背景。侧边栏的呈现规则同样来自 ADRVIEWS 分区位于 Favorites 与 Types 之间且在没有视图时整体隐藏——演示 vault 里只放了active-projects.yml一个视图启动后侧边栏即出现这一项及其匹配计数。后果与工程影响ConsequencesADR 的 Consequences 一节列出的四点都能在仓库里找到落地证据新依赖serde_yamlViewDefinition/FilterNode的序列化、scan_views的解析都依赖它目录自动创建 扫描排除如上节所述首次保存自动建目录.laputa在HIDDEN_DIRS中不被笔记扫描收录git 同步与冲突视图是行级文本文件跨设备同步走标准 git 合并YAML 按行合并的冲突面小排序持久化回写在某个视图被选中时更改列表排序前端会把新的sort写回对应.yml文件经由save_view_cmd因此排序偏好同样参与 git 同步。实践建议结合官方参考文档 site/reference/view-filters.md 与源码语义手写或维护视图文件时可以参考一个视图回答一个重复出现的问题如Active projectstype是 Project 且status是 Active太宽泛就拆成两个视图优先用all分组收窄需要或关系时用嵌套any分组例如状态为 active 或 in-progress 的 Project日期类视图用相对表达式before7 days ago等避免写死日期导致视图过期正则过滤regex: true保留给高级场景且模式编译失败时该条件静默不命中调试时可先用等值条件缩小范围所有字段名先试内置字段type/isA、status、title、body、archived、favorite其余自动落入 frontmatter 属性与关系的回落链——自定义属性无需任何注册即可参与过滤。小结Tolaria 的自定义视图方案用vault 内的.yml文件 客户端条件树求值同时满足了可移植、可同步、可手写编辑三个约束文件格式简单到可以直接纳入 git 工作流条件表达力10 种操作符、任意深度 AND/OR 嵌套、相对日期、wikilink stem 匹配、正则足够覆盖日常知识管理的过滤需求而 Rust 后端保留同一套求值语义供 MCP/CLI 使用保证了应用内与外部 AI 工具查询结果的一致性。【免费下载链接】tolariaDesktop app to manage markdown knowledge bases项目地址: https://gitcode.com/GitHub_Trending/to/tolaria创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
热门专题

继续阅读更多专题内容

围绕企业服务、数字化转型与官网运营的常青话题,持续输出深度内容

企业官网建设指南 企业托管服务模式 财税政策与解读 企业数字化转型 官网SEO与获客 网站安全与运维
配套服务

读完这篇文章,了解更多服务

从整站搭建到SEO布局,17项核心服务助您打造高转化的企业官网

01

企业托管整站搭建

从信息架构到栏目预留,搭建可生长的企业站点骨架,每个页面独立原创设计。...

了解详情
02

规整可信网页设计

雪地靴温暖风原创设计,金属铜线条贯穿全页,拒绝通用模板与AI流水线。...

了解详情
03

企业服务SEO布局

关键词体系与语义化结构,从建站源头为搜索排名而生。...

了解详情
04

业务预约咨询表单

多场景表单与线索收集体系,把访问流量转化为可追踪的销售线索。...

了解详情
05

企业服务站点运维

安全巡检、数据备份与内容更新支持,全年守护网站稳定运行。...

了解详情
06

全终端商务适配

电脑、平板、手机一致呈现,移动端体验与转化同样出色。...

了解详情
需要专业建议?

让专业顾问为您解读行业趋势

关于企业官网建设、SEO获客与数字化转型的任何疑问,欢迎一对一咨询我们的专业顾问。