【Obsidian】ボタンを作れるプラグインMeta Bindの使い方
· 13 min read
Obsidianで、ワンクリックでさまざまな操作ができるボタンを作れる便利なプラグインMeta Bindを紹介します。
![Buttonの例](/_astro/example-buttons.C5dCCDQh.jpg)
悩み
Notionのテンプレートボタンのように「ノートの中に1クリックでいろいろできるボタン」をObsidianでも仕込みたくてインターネットを放浪していました。そんな時に見つけたのがMeta Bindです。
別のプラグイン”Buttons”のREADMEで紹介されていました。
Meta Bindとは?
Meta Bindは、メタデータ(プロパティ)と連携する入力欄やボタンを作ることができるプラグインです。今回はボタンを作る「Buttons」という機能を紹介します。
![Meta Bindのボタンの例](/_astro/button-obcommands.CBYlBwdM.jpg)
Meta Bindの導入
まずはMeta Bindをインストールします。設定は特に弄らなくても使えます。
Buttons機能の紹介
ボタンの作り方と簡単な例を紹介します。
作り方
コードブロックにmeta-bind-button
を指定してYAML形式で書きます。
```meta-bind-buttonここにYAML形式で定義```
定義の例を見てみましょう。style
でボタンのスタイルを決め、label
にボタンのラベル、action
またはactions
に実行内容を書きます。
style: default # 'default' | 'primary' | 'destructive' | 'plain'label: ラベル名actions: - type: command command: command-palette:open - type: input str: help
ちなみに上記のボタンを実行すると、コマンドパレットが開かれてhelp
と入力された状態になります。
コマンド実行
たとえば、Obsidianのコマンドを実行するには次のようにtype
キーをcommand
に指定し、command
キーに実行したいコマンドを書きます。
style: defaultlabel: Meta Bindのヘルプを開くaction: type: command command: obsidian-meta-bind-plugin:open-faq
command
キーの値に書くObsidianのコマンドを何も知らずに探すのは大変です。このコマンド一覧の確認方法はのちほど説明します。
ノートの作成
新しくノートを作る場合はtype
キーにcreateNote
を指定します。その他フォルダやファイル名、ファイルを開くかどうかを指定します。
style: destructivelabel: 新規ノートの作成tooltip: "ホバーで説明も出る!"action: type: createNote folderPath: "inbox" fileName: "New Note" openNote: true
Meta Bindでは、type
に指定した値によってaction
で指定すべきキーが変わります。type
の種類はたくさんあるため、他の種類を知りたい方は公式ドキュメントにアクセスし、サイドバーのButton Actions
をご覧ください。
実例
ここからは筆者が実際に使っている例を紹介します。
dataviewとセットで新しいノート作成ボタン
筆者は、dataviewで表示したノートと同じテンプレートを作成できるボタンをdataviewとセットで設置しています。テンプレートが複数ある場合、ボタンを横並びで設置しています。
![横並びボタン](/_astro/horizontal-buttons.DctoPy6S.jpg)
ボタンのコードブロックの中身もお見せします。
style: primarylabel: プロジェクトを追加hidden: trueid: add-project-defaultaction: type: templaterCreateNote templateFile: "template/work-project.md" folderPath: "inbox/work/project" fileName: "New Note"
type
はtemplaterCreateNote
です。Templaterで用意したテンプレートを使ってファイルを作成します。ファイル名についてはTemplater側で変更するため、ここでは適当にNew Note
となっています。
id
を指定することで、コードブロックを書いた場所以外からでも呼び出せます。呼び出し時にはインラインコードにBUTTON[指定したid]
のように書きます。
`BUTTON[add-project-default]` `BUTTON[add-project-hakusyaku]`
このように、インラインコードでボタンを表示すれば横並び可能です。
そのままだと「コードブロック」「インラインコード」の2箇所で同じボタンが表示されるため、コードブロックのボタン定義ではhidden: true
を指定して非表示にしています。
Obsidianのコマンド一覧を出力する
type
キーにcommand
を指定した時のcommand
キーの値は、Obsidianのコマンドです。.obsidian.vimrcに登場するobcommand
と同じです。
このコマンド一覧を取得するテンプレートとボタンを作っています。
![Obsidianのコマンド一覧を表示](/_astro/button-obcommands.CBYlBwdM.jpg)
style: "destructive"label: 現在のcommand一覧を表示action: type: "insertIntoNote" line: 18 # プロパティ数によって行数が変わるため、各自変更してください value: "template/obcommands.md" templater: true
ボタンを定義するコードブロックの下にTemplaterのテンプレを挿入します。テンプレは次のとおりです。
<%*let cmds = Object.entries(app.commands.commands).sort(v => v[1].id, 'asc');
tR += cmds.map(v => v[1].id).join("\n")%>
dataviewを使う方法もありますが、テキストとして操作できた方が検索もできます。
そのため、dataviewでコマンド一覧を表示するのではなく、「Templaterでコマンド一覧を出力するテンプレ」をMeta Bindで展開します。
作業ログ追加ボタン
筆者は、「タイムスタンプ」+「折りたたみ変換ボタン」を追加するボタンを設置しています。作業ログの記録として使っており、用が済んだら折りたたみへ変換します。
最初からCalloutを使って折りたたんだ状態にすると書き心地が悪いため、後から変換する仕様なのです。
![履歴記録ボタン](/_astro/button-history.DHJz5-NS.jpg)
「折りたたみへ変換」を押すと次の画像のように折りたたまれてボタンも消えます。
![変換後](/_astro/button-after-convert.ClcG8fy3.jpg)
style: primaryicon: corner-left-uplabel: 履歴を追加action: type: "replaceSelf" replacement: "template/button-history.md" templater: true
type
はreplaceSelf
です。ボタン自身をテンプレートと置き換えてくれます。
履歴は上に追加されていくことを示すためにicon
を使っています。icon
に指定できるのはLucideアイコンのようです。
テンプレートの中身全体を一度お見せします。後で小分けにして説明します。
<%* const UID = tp.date.now("YYYYMMDDHHmmss") -%><!-- REPLACE-START-<% UID %> -->## <% tp.date.now("YYYY年MM月DD日 HH:mm") %> <% tp.file.cursor() %><% tp.file.cursor() %><!-- REPLACE-END-<% UID %> -->```meta-bind-buttonstyle: primarylabel: 折りたたみへ変換actions: - type: inlineJS code: | e = app.workspace.activeLeaf.view.editor; s = e.getValue(); const startPattern = "<!-- REPLACE-START-<% UID %>.*-->\n"; const endPattern = "<!-- REPLACE-END-<% UID %>.*-->\n"; const pattern = `${startPattern}([^]*)${endPattern}`; let text = s.match(pattern); if (text === null) { new Notice("対象が見つかりませんでした") } else { let target = text[1]; target = target.replace("## ", "[!note]- "); let newText = ""; for (const line of target.split("\n")) { newText += `> ${line}\n`; } s = s.replace(new RegExp(pattern, "m"), newText) e.setValue(s); - type: "sleep" ms: 3000 - type: "replaceSelf" replacement: "" }```<%* /* 埋め込み先でも以下のボタンを設置することで使える */ -%>```meta-bind-buttonstyle: primaryicon: corner-left-uplabel: 履歴を追加action: type: "replaceSelf" replacement: "template/button-history.md" templater: true```
「作業ログのテンプレート」+「折りたたみへ変換ボタン」+「履歴を追加ボタン」の順です。
実行にはJS Engineプラグインのインストールが必要です。
まず最初がタイムスタンプと実際に作業ログを書く場所です。
<%* const UID = tp.date.now("YYYYMMDDHHmmss") -%><!-- REPLACE-START-<% UID %> -->## <% tp.date.now("YYYY年MM月DD日 HH:mm") %> <% tp.file.cursor() %><% tp.file.cursor() %><!-- REPLACE-END-<% UID %> -->
REPLACE
のコメントアウトは、あとで折りたたみへ変換する範囲を取得するために使います。作業ログは複数の見出しを並行して書くこともあるため、UID
を付けて一意に識別できるようにしています。
この識別のためのテキストをコメントアウトにしておくことで、リーダービューで見るときには非表示になってくれます。
Templaterで1行目<%* %>
が空行として残ってしまうのを防ぐため、閉じる前にダッシュ-
を付けています。Templaterのホワイトスペースの挙動に興味のある人はWhitespace Control - Templaterを読みましょう。
続いて、「折りたたみへ変換するボタン」を見てみましょう。
style: primarylabel: 折りたたみへ変換actions: - type: "replaceSelf" replacement: "" - type: inlineJS code: | # ここにコード。後で説明。
action
ではなくactions
を使うことで変換ボタンでは3つのことをやっています。
- 折りたたみへ変換
- 待機
- 変換ボタンの削除
折りたたみへの変換ではJS Engineを使ってJavaScriptのコードを実行します。複数行にわたって書くため、code
キーの値の最初には|
を指定しています。
変換ボタンは一度使ったら不要であるため、replaceSelf
でボタンを抹消します。すぐに実行すると前述の変換とかち合ってしまうようなので待機してから実行します。
次にcode
で指定した中身です。解説はコメントアウトとして書いておきます。
// ファイルの文章を取得e = app.workspace.activeLeaf.view.editor;s = e.getValue();
// 折りたたみ範囲の取得// UIDの部分は「履歴を追加」のボタンを押した時点でTemplaterによって変換されますconst startPattern = "<!-- REPLACE-START-<% UID %>.*-->\n";const endPattern = "<!-- REPLACE-END-<% UID %>.*-->\n";const pattern = `${startPattern}([^]*)${endPattern}`;let text = s.match(pattern);
if (text === null) { // 折りたたみ範囲が見つからなかったら通知 new Notice("対象が見つかりませんでした")} else { // 見出し部分をCallout表記に変換 let target = text[1]; // []の後に-を付けているのでデフォルトが折りたたみ状態 target = target.replace("## ", "[!note]- "); let newText = ""; for (const line of target.split("\n")) { newText += `> ${line}\n`; }
// 変換したテキストを適用 s = s.replace(new RegExp(pattern, "m"), newText) e.setValue(s);}
今回Calloutの種類は一番無難そうなnote
にしています。サポートされているCalloutの種類はCallouts - Obsidian Helpを見ましょう。
テンプレートの最後の「履歴を追加」ボタンは、最初と同じです。
<%* /* 埋め込み先でも以下のボタンを設置することで使える */ -%>```meta-bind-buttonstyle: primaryicon: corner-left-uplabel: 履歴を追加action: type: "replaceSelf" replacement: "template/button-history.md" templater: true```
作業ログのボタンが必要になったら、テンプレートのこのボタンの部分をコピペすることで設置できます。テンプレートの中にボタンの設置方法が書いてあると分かりやすいです。
Meta Bindを紹介しました。Templaterと組み合わせると効果は抜群です。ボタンを使うとワンクリックでいろいろできるので便利です。