obsidian-bases について
Obsidian Bases Skill は、スキル対応エージェントが Obsidian の保管庫内のノートを動的に表示する YAML 形式の `.base` ファイルを作成・編集できるようにします。フィルター、数式、プロパティ、集計、テーブル・カード・リスト・マップ表示を扱います。
主な機能
- 01`.base` ファイルの作成と編集
- 02全体およびビュー別フィルターの定義
- 03数式プロパティの計算
- 04テーブル、カード、リスト、マップ表示の設定
- 05組み込み関数と集計の利用
活用シーン
- 01保管庫のノートを使った絞り込み式タスク管理
- 02計算フィールド付き読書リストの作成
- 03日付や数値プロパティによるノート集計
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oldwinter/ skills --skill obsidian-basesインストール後、Claude Code で/obsidian-basesを入力して読み込まれたか確認します。
詳細
Obsidian Bases スキル
このスキルを使うと、スキル互換のエージェントが、ビュー、フィルター、数式、および関連するすべての設定を含む、有効な Obsidian Bases(.base)ファイルを作成および編集できます。
概要
Obsidian Bases は、Obsidian の保管庫内のノートを動的に表示するための、YAML ベースのファイルです。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")
フィルター演算子
| 演算子 | 説明 |
|---|---|
== | 等しい |
!= | 等しくない |
> | より大きい |
< | より小さい |
>= | 以上 |
<= | 以下 |
&& | 論理積 |
|| | 論理和 |
! | 論理否定 |
プロパティ
プロパティの3つの種類
- ノートプロパティ - フロントマターから取得します:
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 | すべてのフロントマタープロパティ |
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 | 任意 | 一意な値の数 |
完全な例
タスクトラッカーのベース
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
読書リストのベース
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("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
ベースの埋め込み
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 != ""'