テンプレートは便利
増え続けるテンプレート
メモ/ノート管理アプリ「Obsidian」は便利だ。
特に、ノートによって記載する内容やフォーマットを変える場合、そのテンプレートを使い分けることができる Templater プラグインはほぼ必須といっていいだろう。
似たようなノート群の些細な違いでも、毎回繰り返し発生する手間があるなら、別のテンプレートに分けたくなるのは人情。
ファイルサイズも小さいし、特に邪魔になるものでもないから。
しかしそれゆえにテンプレートは増え続けていく。
新規ノート作成時にどのテンプレートが適当だったか迷うほどに。

選択メニューを作ってみた
そこでノート作成時にテンプレートを選択しやすくなるメニュー用スクリプトを作成してみた。

まずホットキーでテンプレート選択メニューを呼び出す。
テンプレートはグループ分けされていて、該当するグループを選ぶ。

次にそのグループに属するテンプレート一覧が表示される。
このサンプルでは「キャラクター」用テンプレートを選んだ。

ノートを名前を入力してエンター。

「キャラクター」用テンプレートでノートが作成された。
「グループ」「テンプレートの名称」「アイコン」を用いてスムースにテンプレートを選べたと思う。
便利ゆえに煩雑に
テンプレート管理の課題
- 多種多様なノート作りをすれば、テンプレートの種類も増えていく
- 例えばフォルダでグループ分けしたとしても、通常のテンプレート選択では膨大な候補一覧に埋もれる
- 候補の絞り込みにはテンプレートのファイル名を知っておかねばならない
- 利用頻度の少ないテンプレートの存在を忘れがち
理想的な選択機能
- グループ→該当テンプレートと、候補一覧の表示数を絞り込む(ステップは増える)
- ファイル名ではなく、分かりやすい名称とアイコンによる識別
- 絞り込みや選択を数字キーで代用可能
- グループやテンプレートも自由に並び替えたい
Capacities というノートアプリが、作成する内容に沿ったテンプレート(アプリではObject)を選ぶスタイルで、これにちょっと惹かれてた。

そしてMaybeFixさんが非公開の私用プラグインを披露されていて、そこにまさに求めていた姿があった。


スクリプトで解決
ChatGPTに相談
ChatGPTくんに「タイルナビゲーションみたいなメニューを作りたい」と相談をもちかけて、まず出てきたのが以下。

これはリスト型じゃないか、もっと気合いれて考えて!と発破をかけたら、それっぽいものが提示された。

これをベースに好みに仕上げようとしたが、サンプルを触ってみて、考えを変えた。
「タイルメニューはマウス操作を強いられる」「絞り込みや直接項目を選ぶことができない」といったデメリットが目立つから。
タイミングよくMaybeFixさんと少しお話できたが、本人もすでにこの形式のデメリットに気づかれてて、リスト型に変えたとのこと。
結果として上に示した「リスト型」「2ステップ型」の形となった。
Templaterスクリプトと、グループとテンプレートの組み合わせを管理するJSONファイルの2つで構成されている。
- Script_TemplateMenu.md スクリプト
- TemplateMenu.json JSONファイル
- スクリプトとJSON、各種テンプレートはVault直下「/1_Templates/」に置いてあるとします
- 利用される場合は、ファイル名や「★メニュー構成のJSONファイルとテンプレートフォルダのパスを指定」の箇所を適宜書きかえてください。
Script_TemplateMenu.md
<%*
async function showMenu(menuItems, title = "メニューを選択") {
const labels = menuItems.map((item, index) => `${index + 1}. ${item.icon} ${item.label}`);
const values = menuItems.map(item => item.label);
// 戻るオプションを追加
labels.push("0. 🔙 戻る");
values.push("BACK");
const selectedLabel = await tp.system.suggester(labels, values);
return selectedLabel;
}
async function main() {
const fs = this.app.vault.adapter;
// ★メニュー構成のJSONファイルとテンプレートフォルダのパスを指定
const menuFile = "/1_Templates/TemplateMenu.json";
const templateBasePath = "/1_Templates/";
// メニュー構成ファイルを読み込む
const menuData = JSON.parse(await fs.read(menuFile));
while (true) {
// 親メニューの選択
const selectedParentLabel = await showMenu(menuData);
// キャンセルまたはEscでundefinedが返された場合
if (!selectedParentLabel || selectedParentLabel === "BACK") {
return;
}
// 選択された親メニューの子メニューを取得
const parentItem = menuData.find(item => item.label === selectedParentLabel);
if (!parentItem || !parentItem.children) continue;
const childItems = parentItem.children;
// 子メニューの選択
const selectedChildLabel = await showMenu(childItems, parentItem.label);
// 戻る処理
if (!selectedChildLabel || selectedChildLabel === "BACK") {
continue;
}
// テンプレートの読み込みとノート作成
const childItem = childItems.find(item => item.label === selectedChildLabel);
if (childItem) {
const templatePath = templateBasePath + childItem.template;
const content = await fs.read(templatePath);
// ノート名を指定
let fileName = await tp.system.prompt("新しいノートの名前を入力してください");
// 未入力の場合、自動で名前を生成
if (!fileName) {
fileName = "NoTitle_" + tp.date.now("YYYY-MM-DD_HHmmss");
}
// 禁止文字を除去
const filePath = fileName.replace(/[\/\\:*?"<>|]/g, "").replace(/\.md$/, "");
// ノート作成
await tp.file.create_new(content, filePath, true);
return;
}
}
}
// メイン処理開始
await main();
%>
TemplateMenu.json
[
{
"label": "アイデア",
"icon": "💡",
"children": [
{ "label": "キャラクター", "icon": "🧍", "template": "tp_new.md" },
{ "label": "場所", "icon": "📍", "template": "Location.md" },
{ "label": "アイテム", "icon": "⚔️", "template": "Item.md" },
{ "label": "プロット", "icon": "📜", "template": "Plot.md" }
]
},
{
"label": "メモ",
"icon": "📝",
"children": [
{ "label": "資料", "icon": "📄", "template": "Reference.md" },
{ "label": "雑感", "icon": "😊", "template": "Zakkan.md" },
{ "label": "読書", "icon": "📕", "template": "Reading.md" }
]
},
{
"label": "その他",
"icon": "📂",
"children": [
{ "label": "疑問", "icon": "❓", "template": "Question.md" },
{ "label": "日記", "icon": "📅", "template": "Diary.md" }
]
}
]
ホットキーに入れて運用しよう
あとはスクリプトが呼び出しやすいように、「Templater」オプションの Templater hotkeys に登録して、「ホットキー」から登録する。
(2025-05-13 03:23修正)Templater: Createではなく Templater: Insertで運用してください。この場合は他のノートが開いている状態が前提です。


操作の手抜き上等
とりあえず思いつく範囲の基本的な操作は取り入れています。

1ステップ目で作成をキャンセルする場合は、ESCキーか「0. 🔙 戻る」を選択。
2ステップ目で1ステップ目に戻る場合も、ESCキーか「0. 🔙 戻る」を選択。
なので、2ステップ目から作成をキャンセルする場合は、ESCキー2回といった感じ。

上下キーやマウスで選択以外に、デフォルト同様に名称による絞り込みも可能。
この時に先頭につけられた番号が使えるので、楽に選べる。

ノートの名前を入力する際に、未入力でもエンターキーを受け付ける。

すると作成日時から仮名のファイル名をつけられた。
もちろんカスタマイズも
TemplateMenu.jsonをメモ帳などで開き、編集が可能。

例えばグループを増やすなら2行目~11行目までのようなセットをコピー&ペーストで増やせば良い。
グループに属するテンプレートも行単位で増やしたり削ったり。
このJSONファイルの並びで表示される順番も反映される。
注意点としては、JSONファイル形式なので、各セットの末尾(赤い丸の箇所)はカンマ不要です。
他にも応用できそう
例えばこんな使い方
- レビューメモ:書籍や映画など、レビューや記録内容を各テンプレートで。プロパティに書籍ならISBN、映画なら主演などを付加するとか。
- 創作メモ:キャラクター、プロット、アイデアを広げやすいように、メモ毎の項目を揃えておける。
- カレンダー:日次・週次・月次のノートはフォーマットが異なるだろう。
- 住所録:友人知人、仕事関係、ゲーム仲間でテンプレートを変えるなど。
- 仕事でObsidian:業務の各書式・フォーマット毎にテンプレートを用意。
テンプレートはそれこそ人によって種類も数も異なるだろう。
このスクリプトを使って自分なりのテンプレートライブラリーを充実させてください。