mcpField
O
obsidian-bases

obsidian-bases

github.com/oldwinter生产力1038 次安装1 周前更新
代码仓库

关于 obsidian-bases

Obsidian Bases Skill 帮助兼容技能的 Agent 创建和编辑 YAML 格式的 `.base` 文件,用于展示 Obsidian 库中的动态笔记视图。它涵盖筛选器、公式、属性、汇总,以及表格、卡片、列表和地图视图。

主要功能

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

适用场景

  1. 01根据库中笔记构建筛选式任务跟踪器
  2. 02创建带计算字段的阅读清单
  3. 03按日期或数值属性汇总笔记

安装

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

$npx skills add https://github.com/oldwinter/skills --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")'
  
  # Complex expressions
  days_old: '((now() - file.ctime) / 86400000).round(0)'

函数参考

全局函数
函数签名描述
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对日期始终返回 false
日期运算
# 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()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

默认汇总公式

名称输入类型描述
Average数字数学平均值
Min数字最小值
Max数字最大值
Sum数字所有数值之和
Range数字最大值 - 最小值
Median数字数学中位数
Stddev数字标准差
Earliest日期最早日期
Latest日期最晚日期
Range日期最晚日期 - 最早日期
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", "📖", 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