关于 obsidian-bases
obsidian-bases 是用于 Claude Code 的技能,可创建和编辑有效的 Obsidian Bases 文件,并配置笔记视图、筛选器、公式、属性和汇总。
主要功能
- 01创建和编辑 .base 文件
- 02配置表格、卡片、列表和地图视图
- 03定义全局及视图筛选器
- 04计算公式属性和汇总
适用场景
- 01构建任务跟踪器和项目仪表板
- 02按属性或标签整理笔记
- 03为笔记创建计算字段
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ davepoon/ buildwithclaude --skill obsidian-bases安装后在 Claude Code 中输入/obsidian-bases确认已加载。
详细介绍
Obsidian Bases
此技能可让 Claude Code 创建和编辑有效的 Obsidian Bases(.base)文件,包括视图、筛选器、公式及所有相关配置。
概述
Obsidian Bases 是基于 YAML 的文件,用于定义 Obsidian 仓库中笔记的动态视图。Base 文件可以包含多个视图、全局筛选器、公式、属性配置和自定义摘要。
何时使用此技能
- 在 Obsidian 中创建类似数据库的笔记视图
- 构建任务跟踪器、待读列表或项目仪表板
- 按属性或标签筛选和整理笔记
- 创建计算字段或公式字段
- 设置表格、卡片、列表或地图视图
- 在 Obsidian 仓库中处理 .base 文件
文件格式
Base 文件使用 .base 扩展名,内容为有效的 YAML。它们也可以嵌入 Markdown 代码块中。
完整架构
# Global filters apply to ALL views in the base
filters:
# Can be a single filter string
# OR a recursive filter object with and/or/not
and: []
or: []
not: []
# Define formula properties that can be used across all views
formulas:
formula_name: 'expression'
# Configure display names and settings for properties
properties:
property_name:
displayName: "Display Name"
formula.formula_name:
displayName: "Formula Display Name"
file.ext:
displayName: "Extension"
# Define custom summary formulas
summaries:
custom_summary_name: 'values.mean().round(3)'
# Define one or more views
views:
- type: table | cards | list | map
name: "View Name"
limit: 10 # Optional: limit results
groupBy: # Optional: group results
property: property_name
direction: ASC | DESC
filters: # View-specific filters
and: []
order: # Properties to display in order
- file.name
- property_name
- formula.formula_name
summaries: # Map properties to summary formulas
property_name: Average
筛选器语法
筛选器用于缩小结果范围,可以应用于全局或单个视图。
筛选器结构
# Single filter
filters: 'status == "done"'
# AND - all conditions must be true
filters:
and:
- 'status == "done"'
- 'priority > 3'
# OR - any condition can be true
filters:
or:
- file.hasTag("book")
- file.hasTag("article")
# NOT - exclude matching items
filters:
not:
- file.hasTag("archived")
# Nested filters
filters:
or:
- file.hasTag("tag")
- and:
- file.hasTag("book")
- file.hasLink("Textbook")
- not:
- file.hasTag("book")
- file.inFolder("Required Reading")
筛选器运算符
| 运算符 | 描述 |
|---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于或等于 |
<= | 小于或等于 |
&& | 逻辑与 |
|| | 逻辑或 |
! | 逻辑非 |
属性
三种属性类型
- 笔记属性 - 来自 frontmatter:
note.author或仅写author - 文件属性 - 文件元数据:
file.name、file.mtime等 - 公式属性 - 计算得出的值:
formula.my_formula
文件属性参考
| 属性 | 类型 | 描述 |
|---|---|---|
file.name | String | 文件名 |
file.basename | String | 不含扩展名的文件名 |
file.path | String | 文件的完整路径 |
file.folder | String | 父文件夹路径 |
file.ext | String | 文件扩展名 |
file.size | Number | 文件大小(字节) |
file.ctime | Date | 创建时间 |
file.mtime | Date | 修改时间 |
file.tags | List | 文件中的所有标签 |
file.links | List | 文件中的内部链接 |
file.backlinks | List | 链接到此文件的文件 |
file.embeds | List | 笔记中的嵌入内容 |
file.properties | Object | 所有 frontmatter 属性 |
this 关键字
- 在主内容区域:指 Base 文件本身
- 嵌入时:指嵌入所在的文件
- 在侧边栏中:指主内容中的活动文件
公式语法
公式根据属性计算值。公式定义在 formulas 部分中。
formulas:
# Simple arithmetic
total: "price * quantity"
# Conditional logic
status_icon: 'if(done, "check", "pending")'
# String formatting
formatted_price: 'if(price, price.toFixed(2) + " dollars")'
# Date formatting
created: 'file.ctime.format("YYYY-MM-DD")'
# Complex expressions
days_old: '((now() - file.ctime) / 86400000).round(0)'
函数参考
全局函数
| 函数 | 签名 | 描述 |
|---|---|---|
date() | date(string): date | 将字符串解析为日期 |
duration() | duration(string): duration | 解析持续时间字符串 |
now() | now(): date | 当前日期和时间 |
today() | today(): date | 当前日期(时间 = 00:00:00) |
if() | if(condition, trueResult, falseResult?) | 条件判断 |
min() | min(n1, n2, ...): number | 最小数值 |
max() | max(n1, n2, ...): number | 最大数值 |
number() | number(any): number | 转换为数值 |
link() | link(path, display?): Link | 创建链接 |
list() | list(element): List | 若尚未为列表,则将其包装为列表 |
file() | file(path): file | 获取文件对象 |
image() | image(path): image | 创建用于渲染的图像 |
icon() | icon(name): icon | 按名称获取 Lucide 图标 |
html() | html(string): html | 渲染为 HTML |
escapeHTML() | escapeHTML(string): string | 转义 HTML 字符 |
日期函数和字段
字段: date.year、date.month、date.day、date.hour、date.minute、date.second、date.millisecond
| 函数 | 签名 | 描述 |
|---|---|---|
date() | date.date(): date | 移除时间部分 |
format() | date.format(string): string | 使用 Moment.js 模式格式化 |
time() | date.time(): string | 获取时间字符串 |
relative() | date.relative(): string | 以易读形式显示相对时间 |
isEmpty() | date.isEmpty(): boolean | 日期始终不为空 |
日期运算
# Duration units: y/year/years, M/month/months, d/day/days,
# w/week/weeks, h/hour/hours, m/minute/minutes, s/second/seconds
# Add/subtract durations
"date + \"1M\"" # Add 1 month
"date - \"2h\"" # Subtract 2 hours
"now() + \"1 day\"" # Tomorrow
"today() + \"7d\"" # A week from today
# Subtract dates for millisecond difference
"now() - file.ctime"
# Complex duration arithmetic
"now() + (duration('1d') * 2)"
字符串函数
字段: string.length
| 函数 | 描述 |
|---|---|
contains(value) | 检查子字符串 |
containsAll(...values) | 是否包含所有子字符串 |
containsAny(...values) | 是否包含任意子字符串 |
startsWith(query) | 是否以查询内容开头 |
endsWith(query) | 是否以查询内容结尾 |
isEmpty() | 是否为空或不存在 |
lower() | 转换为小写 |
title() | 转换为标题格式 |
trim() | 移除空白字符 |
replace(pattern, replacement) | 替换匹配内容 |
repeat(count) | 重复字符串 |
reverse() | 反转字符串 |
slice(start, end?) | 截取子字符串 |
split(separator, n?) | 拆分为列表 |
数字函数
| 函数 | 描述 |
|---|---|
abs() | 绝对值 |
ceil() | 向上取整 |
floor() | 向下取整 |
round(digits?) | 四舍五入到指定小数位数 |
toFixed(precision) | 固定小数表示法 |
isEmpty() | 不存在 |
列表函数
字段: list.length
| 函数 | 描述 |
|---|---|
contains(value) | 元素是否存在 |
containsAll(...values) | 是否包含所有元素 |
containsAny(...values) | 是否包含任意元素 |
filter(expression) | 按条件筛选(使用 value、index) |
map(expression) | 转换元素(使用 value、index) |
reduce(expression, initial) | 归约为单个值(使用 value、index、acc) |
flat() | 展平嵌套列表 |
join(separator) | 合并为字符串 |
reverse() | 反转顺序 |
slice(start, end?) | 截取子列表 |
sort() | 按升序排序 |
unique() | 移除重复项 |
isEmpty() | 是否没有元素 |
文件函数
| 函数 | 描述 |
|---|---|
asLink(display?) | 转换为链接 |
hasLink(otherFile) | 是否有指向文件的链接 |
hasTag(...tags) | 是否包含任意指定标签 |
hasProperty(name) | 是否有属性 |
inFolder(folder) | 是否位于文件夹或子文件夹中 |
视图类型
表格视图
views:
- type: table
name: "My Table"
order:
- file.name
- status
- due_date
summaries:
price: Sum
count: Average
卡片视图
views:
- type: cards
name: "Gallery"
order:
- file.name
- cover_image
- description
列表视图
views:
- type: list
name: "Simple List"
order:
- file.name
- status
地图视图
需要纬度/经度属性和 Maps 插件。
views:
- type: map
name: "Locations"
默认汇总公式
| 名称 | 输入类型 | 描述 |
|---|---|---|
Average | 数字 | 数学平均值 |
Min | 数字 | 最小值 |
Max | 数字 | 最大值 |
Sum | 数字 | 所有数值之和 |
Range | 数字 | 最大值 - 最小值 |
Median | 数字 | 数学中位数 |
Stddev | 数字 | 标准差 |
Earliest | 日期 | 最早日期 |
Latest | 日期 | 最晚日期 |
Checked | 布尔值 | true 值的数量 |
Unchecked | 布尔值 | false 值的数量 |
Empty | 任意 | 空值的数量 |
Filled | 任意 | 非空值的数量 |
Unique | 任意 | 唯一值的数量 |
完整示例
任务跟踪 Base
filters:
and:
- file.hasTag("task")
- 'file.ext == "md"'
formulas:
days_until_due: 'if(due, ((date(due) - today()) / 86400000).round(0), "")'
is_overdue: 'if(due, date(due) < today() && status != "done", false)'
priority_label: 'if(priority == 1, "High", if(priority == 2, "Medium", "Low"))'
properties:
status:
displayName: Status
formula.days_until_due:
displayName: "Days Until Due"
formula.priority_label:
displayName: Priority
views:
- type: table
name: "Active Tasks"
filters:
and:
- 'status != "done"'
order:
- file.name
- status
- formula.priority_label
- due
- formula.days_until_due
groupBy:
property: status
direction: ASC
summaries:
formula.days_until_due: Average
- type: table
name: "Completed"
filters:
and:
- 'status == "done"'
order:
- file.name
- completed_date
阅读清单 Base
filters:
or:
- file.hasTag("book")
- file.hasTag("article")
formulas:
reading_time: 'if(pages, (pages * 2).toString() + " min", "")'
status_icon: 'if(status == "reading", "reading", if(status == "done", "done", "to-read"))'
year_read: 'if(finished_date, date(finished_date).year, "")'
properties:
author:
displayName: Author
formula.status_icon:
displayName: ""
formula.reading_time:
displayName: "Est. Time"
views:
- type: cards
name: "Library"
order:
- cover
- file.name
- author
- formula.status_icon
filters:
not:
- 'status == "dropped"'
- type: table
name: "Reading List"
filters:
and:
- 'status == "to-read"'
order:
- file.name
- author
- pages
- formula.reading_time
项目笔记 Base
filters:
and:
- file.inFolder("Projects")
- 'file.ext == "md"'
formulas:
last_updated: 'file.mtime.relative()'
link_count: 'file.links.length'
summaries:
avgLinks: 'values.filter(value.isType("number")).mean().round(1)'
properties:
formula.last_updated:
displayName: "Updated"
formula.link_count:
displayName: "Links"
views:
- type: table
name: "All Projects"
order:
- file.name
- status
- formula.last_updated
- formula.link_count
summaries:
formula.link_count: avgLinks
groupBy:
property: status
direction: ASC
- type: list
name: "Quick List"
order:
- file.name
- status
每日笔记索引
filters:
and:
- file.inFolder("Daily Notes")
- '/^\d{4}-\d{2}-\d{2}$/.matches(file.basename)'
formulas:
word_estimate: '(file.size / 5).round(0)'
day_of_week: 'date(file.basename).format("dddd")'
properties:
formula.day_of_week:
displayName: "Day"
formula.word_estimate:
displayName: "~Words"
views:
- type: table
name: "Recent Notes"
limit: 30
order:
- file.name
- formula.day_of_week
- formula.word_estimate
- file.mtime
嵌入 Bases
嵌入 Markdown 文件:
![[MyBase.base]]
![[MyBase.base#View Name]]
YAML 引号规则
- 对包含双引号的公式使用单引号:
'if(done, "Yes", "No")' - 对简单字符串使用双引号:
"My View Name" - 在复杂表达式中正确转义嵌套引号
常见模式
按标签筛选
filters:
and:
- file.hasTag("project")
按文件夹筛选
filters:
and:
- file.inFolder("Notes")
按日期范围筛选
filters:
and:
- 'file.mtime > now() - "7d"'
按属性值筛选
filters:
and:
- 'status == "active"'
- 'priority >= 3'
Combine Multiple Conditions
filters:
or:
- and:
- file.hasTag("important")
- 'status != "done"'
- and:
- 'priority == 1'
- 'due != ""'
References
评论
支持 Markdown