mcpField
O
obsidian-bases

obsidian-bases

github.com/mavscui生产力19361 次安装33 周前更新
代码仓库

关于 obsidian-bases

obsidian-bases 是供兼容技能的 Agent 使用的技能,可创建和编辑 Obsidian Bases 的 .base 文件。它涵盖 YAML 配置、筛选器、公式和多种视图,适合整理 Obsidian vault 中的动态笔记视图。

主要功能

  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/mavscui/agent-skills-hunter --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