mcpField
O
obsidian-bases

obsidian-bases

github.com/kepano生产力50.3k80.4k 次安装6 周前更新
代码仓库

关于 obsidian-bases

obsidian-bases 是用于编写和验证 Obsidian `.base` 文件的技能,介绍 YAML 筛选器、公式以及表格、卡片、列表和地图视图,以便按属性整理笔记。

主要功能

  1. 01创建基于 YAML 的 `.base` 文件
  2. 02按标签、文件夹、属性或日期筛选笔记
  3. 03根据笔记和文件属性定义公式
  4. 04配置表格、卡片、列表和地图视图
  5. 05验证语法并排查公式问题

适用场景

  1. 01用带标签的笔记构建任务跟踪器
  2. 02创建包含计算字段的阅读列表
  3. 03按日期或文件夹索引每日笔记

安装

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

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

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

附带文件references/FUNCTIONS_REFERENCE.md

详细介绍

Obsidian Bases 技能

工作流

  1. 创建文件:在库中创建一个包含有效 YAML 内容的 .base 文件
  2. 定义范围:添加 filters 以选择要显示的笔记(按标签、文件夹、属性或日期)
  3. 添加公式(可选):在 formulas 部分定义计算属性
  4. 配置视图:添加一个或多个视图(table、cards、list 或 map),并用 order 指定要显示的属性
  5. 验证:确认文件是有效的 YAML,没有语法错误。检查所有引用的属性和公式是否存在。常见问题:包含特殊 YAML 字符的未加引号字符串、公式表达式中引号不匹配、引用 formula.X 但未在 formulas 中定义 X
  6. 在 Obsidian 中测试:在 Obsidian 中打开 .base 文件,确认视图正确渲染。如果显示 YAML 错误,请查看下方的引号规则

Schema

Base 文件使用 .base 扩展名,并包含有效的 YAML。

# Global filters apply to ALL views in the base
filters:
  # Can be a single filter string
  # OR a recursive filter object with exactly ONE key: and, or, or not
  and:
    - 'status == "active"'
    - not:
        - 'file.hasTag("archived")'

# 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 follow the same rules
      and:
        - 'status == "active"'
    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、String、Number、List、File、Link、Object、RegExp)的完整参考,请参见 FUNCTIONS_REFERENCE.md。

函数签名描述
date()date(string): date将字符串解析为日期(YYYY-MM-DD HH:mm:ss)
now()now(): date当前日期和时间
today()today(): date当前日期(时间 = 00:00:00)
if()if(condition, trueResult, falseResult?)条件判断
duration()duration(string): duration解析时长字符串
file()file(path): file获取文件对象
link()link(path, display?): Link创建链接
Duration 类型

两个日期相减时,结果是 Duration 类型(不是数字)。

Duration 字段: duration.days、duration.hours、duration.minutes、duration.seconds、duration.milliseconds

重要: 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
"(date(due_date) - today()).days.round(0)"           # Rounded days

# 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
"now() + \"1 day\""       # Tomorrow
"today() + \"7d\""        # A week from today
"now() - file.ctime"      # Returns Duration
"(now() - file.ctime).days"  # Get days as number

视图类型

表格视图
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所有数值之和
RangeNumberMax - Min
MedianNumber数学中位数
StddevNumber标准差
EarliestDate最早的日期
LatestDate最晚的日期
RangeDateLatest - Earliest
CheckedBoolean为 true 的值的数量
UncheckedBoolean为 false 的值的数量
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
每日笔记索引
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"
  • 在复杂表达式中正确转义嵌套引号

故障排查

YAML 语法错误

未加引号的特殊字符:包含 :、{、}、[、]、,、&、*、#、?、|、-、<、>、=、!、%、@、` 的字符串必须加引号。

# WRONG - colon in unquoted string
displayName: Status: Active

# CORRECT
displayName: "Status: Active"

公式中的引号不匹配:当公式包含双引号时,用单引号将整个公式包裹起来。

# WRONG - double quotes inside double quotes
formulas:
  label: "if(done, "Yes", "No")"

# CORRECT - single quotes wrapping double quotes
formulas:
  label: 'if(done, "Yes", "No")'
常见公式错误

未访问字段的时长运算:日期相减返回的是 Duration,而不是数字。务必访问 .days、.hours 等。

# WRONG - Duration is not a number
"(now() - file.ctime).round(0)"

# CORRECT - access .days first, then round
"(now() - file.ctime).days.round(0)"

缺少空值检查:属性可能并非存在于所有笔记上。使用 if() 进行防护。

# WRONG - crashes if due_date is empty
"(date(due_date) - today()).days"

# CORRECT - guard with if()
'if(due_date, (date(due_date) - today()).days, "")'

引用未定义的公式:确保 order 或 properties 中的每个 formula.X 在 formulas 中都有匹配的条目。

# This will fail silently if 'total' is not defined in formulas
order:
  - formula.total

# Fix: define it
formulas:
  total: "price * quantity"

参考

评论

支持 Markdown