mcpField
O
obsidian-bases

obsidian-bases

github.com/jackjin1997生产力1336 次安装19 周前更新
代码仓库

关于 obsidian-bases

为兼容 skills 的 Agent 提供 Obsidian Bases 文件编写指导,可创建和编辑包含视图、筛选器、公式及相关配置的有效 .base 文件。适合需要在 Obsidian 笔记库中定义动态笔记视图的用户。

主要功能

  1. 01创建和编辑 .base 文件
  2. 02配置表格、卡片和列表视图
  3. 03设置全局及视图筛选器
  4. 04使用公式和属性
  5. 05配置汇总计算

适用场景

  1. 01构建任务跟踪视图
  2. 02整理阅读清单
  3. 03汇总项目笔记
  4. 04索引每日笔记

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jackjin1997/clawforge --skill obsidian-bases

安装后在 Claude Code 中输入/obsidian-bases确认已加载。

详细介绍

Obsidian Bases 技能

此技能可让兼容技能的 Agent 创建和编辑有效的 Obsidian Bases(.base)文件,包括视图、筛选器、公式及所有相关配置。

概述

Obsidian Bases 是基于 YAML 的文件,用于定义 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")
筛选器运算符
运算符描述
==等于
!=不等于
>大于
<小于
>=大于或等于
<=小于或等于
&&逻辑与
||逻辑或
!逻辑非

属性

三种属性类型
  1. 笔记属性 - 来自 frontmatter:note.author 或仅使用 author
  2. 文件属性 - 文件元数据:file.name、file.mtime 等
  3. 公式属性 - 计算得出的值:formula.my_formula
文件属性参考
属性类型描述
file.nameString文件名
file.basenameString不含扩展名的文件名
file.pathString文件的完整路径
file.folderString父文件夹路径
file.extString文件扩展名
file.sizeNumber文件大小(字节)
file.ctimeDate创建时间
file.mtimeDate修改时间
file.tagsList文件中的所有标签
file.linksList文件中的内部链接
file.backlinksList链接到此文件的文件
file.embedsList笔记中的嵌入内容
file.propertiesObject所有 frontmatter 属性
this 关键字
  • 在主内容区域中:指 Base 文件本身
  • 嵌入时:指嵌入该内容的文件
  • 在侧边栏中:指主内容中的活动文件

公式语法

公式根据属性计算值。定义在 formulas 部分中。

formulas:
  # Simple arithmetic
  total: "price * quantity"

  # Conditional logic
  status_icon: 'if(done, "✅", "⏳")'

  # String formatting
  formatted_price: 'if(price, price.toFixed(2) + " dollars")'

  # Date formatting
  created: 'file.ctime.format("YYYY-MM-DD")'

  # Calculate days since created (use .days for Duration)
  days_old: '(now() - file.ctime).days'

  # Calculate days until due date
  days_until_due: 'if(due_date, (date(due_date) - today()).days, "")'

函数参考

全局函数
函数签名描述
date()date(string): date将字符串解析为日期。格式:YYYY-MM-DD HH:mm:ss
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 字符
任意类型函数
函数签名描述
isTruthy()any.isTruthy(): boolean转换为布尔值
isType()any.isType(type): boolean检查类型
toString()any.toString(): string转换为字符串
日期函数和字段

字段: 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 类型

减去两个日期时,结果是 Duration 类型(而非数字)。Duration 有自己的属性和方法。

Duration 字段:

字段类型描述
duration.daysNumber持续时间的总天数
duration.hoursNumber持续时间的总小时数
duration.minutesNumber持续时间的总分钟数
duration.secondsNumber持续时间的总秒数
duration.millisecondsNumber持续时间的总毫秒数

重要: Duration 不直接支持 .round()、.floor()、.ceil()。必须先访问一个数字字段(如 .days),然后再应用数字函数。

# CORRECT: Calculate days between dates
"(date(due_date) - today()).days"                    # Returns number of days
"(now() - file.ctime).days"                          # Days since created

# CORRECT: Round the numeric result if needed
"(date(due_date) - today()).days.round(0)"           # Rounded days
"(now() - file.ctime).hours.round(0)"                # Rounded hours

# WRONG - will cause error:
# "((date(due) - today()) / 86400000).round(0)"      # Duration doesn't support division then round
日期运算
# 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 returns Duration type
"now() - file.ctime"                    # Returns Duration
"(now() - file.ctime).days"             # Get days as number
"(now() - file.ctime).hours"            # Get hours as number

# Complex duration arithmetic
"now() + (duration('1d') * 2)"
字符串函数

字段: string.length

函数签名描述
contains()string.contains(value): boolean检查子字符串
containsAll()string.containsAll(...values): boolean所有子字符串均存在
containsAny()string.containsAny(...values): boolean任一子字符串存在
startsWith()string.startsWith(query): boolean是否以查询字符串开头
endsWith()string.endsWith(query): boolean是否以查询字符串结尾
isEmpty()string.isEmpty(): boolean为空或不存在
lower()string.lower(): string转为小写
title()string.title(): string转为标题大小写
trim()string.trim(): string移除空白字符
replace()string.replace(pattern, replacement): string替换模式
repeat()string.repeat(count): string重复字符串
reverse()string.reverse(): string反转字符串
slice()string.slice(start, end?): string子字符串
split()string.split(separator, n?): list拆分为列表
数字函数
函数签名描述
abs()number.abs(): number绝对值
ceil()number.ceil(): number向上取整
floor()number.floor(): number向下取整
round()number.round(digits?): number四舍五入到指定位数
toFixed()number.toFixed(precision): string定点表示法
isEmpty()number.isEmpty(): boolean不存在
列表函数

字段: list.length

函数签名描述
contains()list.contains(value): boolean元素是否存在
containsAll()list.containsAll(...values): boolean所有元素均存在
containsAny()list.containsAny(...values): boolean任一元素存在
filter()list.filter(expression): list按条件筛选(使用 value、index)
map()list.map(expression): list转换元素(使用 value、index)
reduce()list.reduce(expression, initial): any将列表归约为单个值(使用 value、index、acc)
flat()list.flat(): list展平嵌套列表
join()list.join(separator): string拼接为字符串
reverse()list.reverse(): list反转顺序
slice()list.slice(start, end?): list子列表
sort()list.sort(): list升序排序
unique()list.unique(): list移除重复项
isEmpty()list.isEmpty(): boolean没有元素
文件函数
函数签名描述
asLink()file.asLink(display?): Link转换为链接
hasLink()file.hasLink(otherFile): boolean是否链接到文件
hasTag()file.hasTag(...tags): boolean是否包含任一标签
hasProperty()file.hasProperty(name): boolean是否包含属性
inFolder()file.inFolder(folder): boolean是否位于文件夹或子文件夹中
链接函数
函数签名描述
asFile()link.asFile(): file获取文件对象
linksTo()link.linksTo(file): boolean是否链接到文件
对象函数
函数签名描述
isEmpty()object.isEmpty(): boolean没有属性
keys()object.keys(): list键列表
values()object.values(): list值列表
正则表达式函数
函数签名描述
matches()regexp.matches(string): boolean测试是否匹配

视图类型

表格视图
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"
    # Map-specific settings for lat/lng properties

默认汇总公式

名称输入类型描述
AverageNumber数学平均值
MinNumber最小值
MaxNumber最大值
SumNumber所有数值之和
RangeNumber最大值 - 最小值
MedianNumber数学中位数
StddevNumber标准差
EarliestDate最早日期
LatestDate最晚日期
RangeDate最晚日期 - 最早日期
CheckedBooleantrue 值的数量
UncheckedBooleanfalse 值的数量
EmptyAny空值的数量
FilledAny非空值的数量
UniqueAny唯一值的数量

完整示例

任务跟踪器 Base
filters:
  and:
    - file.hasTag("task")
    - 'file.ext == "md"'

formulas:
  days_until_due: 'if(due, (date(due) - today()).days, "")'
  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", "📖", if(status == "done", "✅", "📚"))'
  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'
合并多个条件
filters:
  or:
    - and:
        - file.hasTag("important")
        - 'status != "done"'
    - and:
        - 'priority == 1'
        - 'due != ""'

参考资料

评论

支持 Markdown