【Obsidian】ボタンを作れるプラグインMeta Bindの使い方

· 13 min read

Obsidianで、ワンクリックでさまざまな操作ができるボタンを作れる便利なプラグインMeta Bindを紹介します。

Buttonの例

悩み

Notionのテンプレートボタンのように「ノートの中に1クリックでいろいろできるボタン」をObsidianでも仕込みたくてインターネットを放浪していました。そんな時に見つけたのがMeta Bindです。

別のプラグイン”Buttons”のREADMEで紹介されていました。

Meta Bindとは?

Meta Bindは、メタデータ(プロパティ)と連携する入力欄やボタンを作ることができるプラグインです。今回はボタンを作る「Buttons」という機能を紹介します。

Meta Bindのボタンの例

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: default
label: Meta Bindのヘルプを開く
action:
type: command
command: obsidian-meta-bind-plugin:open-faq

commandキーの値に書くObsidianのコマンドを何も知らずに探すのは大変です。このコマンド一覧の確認方法はのちほど説明します。

ノートの作成

新しくノートを作る場合はtypeキーにcreateNoteを指定します。その他フォルダやファイル名、ファイルを開くかどうかを指定します。

style: destructive
label: 新規ノートの作成
tooltip: "ホバーで説明も出る!"
action:
type: createNote
folderPath: "inbox"
fileName: "New Note"
openNote: true

Meta Bindでは、typeに指定した値によってactionで指定すべきキーが変わります。
typeの種類はたくさんあるため、他の種類を知りたい方は公式ドキュメントにアクセスし、サイドバーのButton Actionsをご覧ください。

実例

ここからは筆者が実際に使っている例を紹介します。

dataviewとセットで新しいノート作成ボタン

筆者は、dataviewで表示したノートと同じテンプレートを作成できるボタンをdataviewとセットで設置しています。テンプレートが複数ある場合、ボタンを横並びで設置しています。

横並びボタン

ボタンのコードブロックの中身もお見せします。

style: primary
label: プロジェクトを追加
hidden: true
id: add-project-default
action:
type: templaterCreateNote
templateFile: "template/work-project.md"
folderPath: "inbox/work/project"
fileName: "New Note"

typetemplaterCreateNoteです。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のコマンド一覧を表示
style: "destructive"
label: 現在のcommand一覧を表示
action:
type: "insertIntoNote"
line: 18 # プロパティ数によって行数が変わるため、各自変更してください
value: "template/obcommands.md"
templater: true

ボタンを定義するコードブロックの下にTemplaterのテンプレを挿入します。テンプレは次のとおりです。

template/obcommands.md
<%*
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を使って折りたたんだ状態にすると書き心地が悪いため、後から変換する仕様なのです。

履歴記録ボタン

「折りたたみへ変換」を押すと次の画像のように折りたたまれてボタンも消えます。

変換後
style: primary
icon: corner-left-up
label: 履歴を追加
action:
type: "replaceSelf"
replacement: "template/button-history.md"
templater: true

typereplaceSelfです。ボタン自身をテンプレートと置き換えてくれます。
履歴は上に追加されていくことを示すためにiconを使っています。iconに指定できるのはLucideアイコンのようです。

テンプレートの中身全体を一度お見せします。後で小分けにして説明します。

template/button-history.md
<%* 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-button
style: primary
label: 折りたたみへ変換
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-button
style: primary
icon: corner-left-up
label: 履歴を追加
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: primary
label: 折りたたみへ変換
actions:
- type: "replaceSelf"
replacement: ""
- type: inlineJS
code: |
# ここにコード。後で説明。

actionではなくactionsを使うことで変換ボタンでは3つのことをやっています。

  1. 折りたたみへ変換
  2. 待機
  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-button
style: primary
icon: corner-left-up
label: 履歴を追加
action:
type: "replaceSelf"
replacement: "template/button-history.md"
templater: true
```

作業ログのボタンが必要になったら、テンプレートのこのボタンの部分をコピペすることで設置できます。テンプレートの中にボタンの設置方法が書いてあると分かりやすいです。


Meta Bindを紹介しました。Templaterと組み合わせると効果は抜群です。ボタンを使うとワンクリックでいろいろできるので便利です。