ObsidianでNotionみたいなカレンダービューを作る方法
ObsidianのCalendarプラグインはデイリーノートのナビゲーションが目的であるため、Notionのカレンダービューのような使い勝手ではありません。
そこで、Notionのような「ノートへのリンクとタイトルが並ぶカレンダービュー」をObsidianで作ってみました。
2024年10月22日追記。
せっかくなので自分でプラグインを作ってみました。Obsidian Embed Calendarをというものです。
別の記事Obsidianの埋め込みカレンダービュープラグインの紹介に書きました。
どんなものができたのか

筆者がカレンダービューを使うにあたり、必要な要件を次のように考えました。
- 指定したプロパティに基づいてノートの一覧をカレンダー表示
- リンクテキストはfrontmatterのタイトル
- 「前の月」「次の月」へ切り替えるボタン
- ピッカーで該当する月へ切り替えるボタン
- 埋め込みに対応
既存のプラグイン1つだけでこれを満たせるものはありませんでしたが、複数組み合わせれば実現できましたのでその方法を紹介します。
ただし、Notionのような「ドラッグ&ドロップによる日付変更」には対応はしていない点に注意です。これも実現したかったのですが、必須条件ではないため今回は諦めました。
必要なプラグインのインストール
まず必要なプラグインのインストールリンクを並べておきます。
役割とドキュメントのリンク
次に、各プラグインの役割と公式ドキュメントへのリンクを書いておきます。
Dataview
Dataviewは指定したノートを集めてプロパティを参照するために使います。
設定でEnable JavaScript Queries
はオンにしてください。
Habit
Habit CalendarはDataviewを使ってカレンダーを表示できるプラグインです。
必要に応じて設定で曜日ラベルを変更してください。

Meta Bind
Meta Bindはノート内にボタンや入力欄を配置してインタラクティブな操作を可能にします。
設定はデフォルトのままで大丈夫です。
プロパティの作成
ここから実際にカレンダービューを作ります。
ビューを設置するノートを用意し、日付タイプのプロパティ_month
を追加して適当な日付を入力しておきます。

プロパティの名前は何でもいいです。変えた人はこの記事の_month
の部分を読み替えてください。
カレンダービューを表示する
dataviewjs
のコードブロックに次のように書きます。次の項目から小分けにして解説するのでご安心を。
const _month = dv.date(dv.current().file.frontmatter._month);const monthTest = new RegExp(_month.toFormat("yyyy年MM月"))const groupByDate = Object.groupBy(dv.pages('"inbox/test"') .filter(p => monthTest.test(p.file.frontmatter["endDate"])) , (p => { return p.file.frontmatter["endDate"]}))const table = Object.keys(groupByDate).map(key => { const links = groupByDate[key].map(p => `[[${p.file.path}|${p.file.frontmatter.title.substring(0, 28)}]]` ) return { date: key, content: links.join("\n\n"), link: groupByDate[key][0].file.path, }})renderHabitCalendar(this.container, dv, { format: "markdown", year: _month.year, month: _month.month, data: table})
ノートを集める
まず1行目は先ほど追加したプロパティ_month
を取得し、扱いやすい形に変換しています。
const _month = dv.date(dv.current().file.frontmatter._month);
dv.date
を使うとLuxonのDateTime
オブジェクトになります。_month.year
や_month.plus({month:1})
のような扱いができます。
次に、プロパティ_month
で指定した年と月に当てはまるノートを、日付ごとのリストにして集めます。
const monthTest = new RegExp(_month.toFormat("yyyy年MM月"))const groupByDate = Object.groupBy(dv.pages('"inbox/test"') .filter(p => monthTest.test(p.file.frontmatter["endDate"])) , (p => { return p.file.frontmatter["endDate"]}))
今回、カレンダービューに表示するノートは次のように定義しました。ここらへんは各自のノートに合わせて変えましょう。
- フォルダ
inbox/test
の中にあるノート - 日付のプロパティは
endDate
- 日付のフォーマットは
2024年4月24日(水)
のような形式

これに対し、プロパティ_month
は2024-04-24
のように異なる形式です。そのため、プロパティ_month
を日付プロパティendDate
のフォーマットに変換してからノートを集めています。toFormat
はLuxonの関数です。
レンダリング
ここから先はHabit Calendarの出番です。まずはノート情報をHabit Calendarで扱えるように加工します。
const table = Object.keys(groupByDate) .map(key => { const links = groupByDate[key].map(p => `[[${p.file.path}|${p.file.frontmatter.title.substring(0, 28)}]]` ) return { date: key, content: links.join("\n\n"), link: groupByDate[key][0].file.path, } })
frontmatterのtitleは28文字以内に切り出し、[[パス|tile]]
のようにリンク化します。ノートが複数ある場合は改行しています。
return
に書いてあるlink
は、「カレンダーで日付にカーソルを合わせた時に表示されるリンク」です。今回は適当に配列の最初のノートのパスにしておきました。
あとはレンダリングするだけです。
renderHabitCalendar(this.container, dv, { format: "markdown", year: _month.year, month: _month.month, data: table})
ボタンの作成
カレンダービューの表示はできました。
ここからは併せて設置しておくと便利なボタンの作成です。
ボタンの配置
先にボタンを表示するインラインコードをノートに書きます。場所はカレンダーの上がよいでしょう。
`BUTTON[my-previous-month-button]` `INPUT[datePicker:_month]` `BUTTON[my-refresh-button]` `BUTTON[my-next-month-button]`
このBUTTON[id]
はMeta BindのInline Buttonという機能です。のちほど定義するボタンのid
を書いておきます。
まだ定義していないため、表示はエラーになります。

INPUT[type:property]
はMeta BindのInput Fieldという機能です。ノートのプロパティを更新できるボタンを表示できます。
今回は日付ピッカーを使ってプロパティ_month
を操作します。
プロパティの方にあるピッカーは埋め込みでは表示されないため、このようにノート内で操作できるようにしています。

dataview更新ボタンの設置
DataviewのRefresh Interval
を長く設定したりAutomatic View Refreshing
をオフにしている人向けのボタンです。
meta-bind-button
のコードブロックの中に次のように定義しましょう。
style: defaulticon: refresh-cwlabel: 最新のテーブルを取得id: my-refresh-buttonhidden: trueaction: type: command command: dataview:dataview-rebuild-current-view
さきほど設置した日付ピッカーを押してプロパティが更新され後に押します。任意のタイミングでDataviewの描画を更新できます。
前の月と次の月
カレンダービューを使うなら、「前の月」「次の月」をワンクリックで移動したいですよね。meta-bind-button
のコードブロックの中に次のように定義しましょう。
style: defaulticon: arrow-leftlabel: 前の月へid: my-previous-month-buttonhidden: trueactions: - type: updateMetadata bindTarget: _month evaluate: true value: "this.app.plugins.plugins['dataview'].api.date(x).minus({month:1}).toISODate()" - type: sleep ms: 500 - type: command command: dataview:dataview-rebuild-current-view
このボタンで実行するのは次の3つです。
- プロパティ
_month
を1か月前にする - 書き換えのために少し待機
- dataviewを再読み込みする
2と3は、Dataviewの「Refresh Interval
を長く設定している」「Automatic View Refreshing
をオフにしている」という人以外は不要です。
Meta Bindでは、updatemetadata
タイプを使うことでプロパティを更新できるボタンを作れます。今回はその機能を使ってプロパティ_month
を書き換えています。value
にJavaScriptの式を書きます。x
は前の値が代入されます。
「次の月へ」ボタンもほぼ同じです。
style: defaulticon: arrow-rightlabel: 次の月へid: my-next-month-buttonhidden: trueactions: - type: updateMetadata bindTarget: _month evaluate: true value: "this.app.plugins.plugins['dataview'].api.date(x).plus({month:1}).toISODate()" - type: sleep ms: 500 - type: command command: dataview:dataview-rebuild-current-view
これでカレンダービューの完成です。

埋め込み時の注意
埋め込んだ場合、テーマによってはボタンと「ノートを開くリンク」が被ってしまう場合があります。

そんなときは、ボタンの前に1行追加してスペースを開けてあげれば問題ありません。

正常であれば、ボタンの上にカーソルを持っていくと画像のように「ツールチップが表示される」などの変化が起こります。
Obsidianでノートリンクを表示するカレンダービューを作ってみました。本来Habit Calendarは習慣トラッカー的に使うプラグインのようですが、まあそれはそれ。
実現できたので各制作者に感謝です。
冒頭にも書きましたが、別の記事Obsidianの埋め込みカレンダービュープラグインの紹介で自作プラグインも紹介していますので併せてどうぞ。