obsidian-bases について
skills 対応エージェントが、ビュー、フィルター、数式などを含む有効な Obsidian Bases ファイルを作成・編集するためのスキルです。Obsidian の保管庫でノートの動的なビューを定義する用途に向いています。
主な機能
- 01.base ファイルの作成と編集
- 02テーブル、カード、リストビューの設定
- 03全体およびビュー別フィルター
- 04数式とプロパティの利用
- 05集計計算の設定
活用シーン
- 01タスク管理ビューの作成
- 02読書リストの整理
- 03プロジェクトノートの集約
- 04デイリーノートの索引作成
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jackjin1997/ clawforge --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")'
# 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 | 日付の場合は常に false |
Duration 型
2 つの日付を減算すると、結果は数値ではなく Duration 型になります。Duration には固有のプロパティとメソッドがあります。
Duration フィールド:
| フィールド | 型 | 説明 |
|---|---|---|
duration.days | Number | Duration の合計日数 |
duration.hours | Number | Duration の合計時間数 |
duration.minutes | Number | Duration の合計分数 |
duration.seconds | Number | Duration の合計秒数 |
duration.milliseconds | Number | Duration の合計ミリ秒数 |
重要: 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
デフォルトの集計数式
| 名前 | 入力タイプ | 説明 |
|---|---|---|
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()).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
読書リストのベース
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 != ""'