本記事は農工大アドベントカレンダー(シーズン2)24日目の記事です。
はじめに
本記事はObsidianを使い始めた筆者が自分の使いやすさを重視しながら試行錯誤を行った記録です。まだ発展途上の段階であるため、間違い等が含まれている可能性があります。
また、本記事内で紹介しているテンプレートはあくまでも一例です。このテンプレートを使用したことによる事象の一切について筆者は責任を負いません。
御託はこのあたりにして早速始めていきましょう〜
完成品のプレビュー
本記事で紹介する内容を使用した場合、最終的に以下のようなものが出来上がります。
(ObsidianのテーマはTokyo Nightを利用しています)
ダッシュボード
論文
実験
また、研究ノートのフォルダ構造は次のようになります。
<Obsidianのルートフォルダ>
└ 07-Researches/
├ Papers/
│ ├ <論文ノート>
│ ├ <論文ノート>
│ ...
│
├ <研究名>
│ ├ Experiments/
│ │ ├ <実験ノート>
│ │ ├ <実験ノート>
│ │ ...
│ └ <研究名>-Dashboard
│
├ <研究名>
│ ├ Experiments/
│ │ ├ <実験ノート>
│ │ ├ <実験ノート>
│ │ ...
│ └ <研究名>-Dashboard
│
...
下準備
今回のテンプレートは以下のプラグインを利用するので最初に導入しておいてください。
- Dataview
- Meta Bind
- MetaEdit(要らないかも)
- Templater
プラグインの導入方法と各プラグインの解説は本記事では行いません。詳細については他に記事を参照してください。
ダッシュボードの作成
まずはダッシュボードを作って行きましょう。

先の画像の再掲ですが、ダッシュボードは2つのデータビューと2つのボタンで構成されています。
Conduct experimentボタンを作成
最初に1つ目のConduct experimentのボタンを作成していきます。
ボタンはmeta-bind-buttonというコードブロック内に専用のyamlを記述することで作成することができます。(iconの部分に指定する名前はLucide Iconで確認できます)
style: primary
icon: flask-conical
label: "Conduct experiment"
id: conduct-new-experiment
hidden: true
action:
type: "runTemplaterFile"
templateFile: "99-System/commands/create_experiment"
ボタン内にtemplateFile: 99-System/commands/create_experimentという記述がありますが、これはこのボタンが押されたときに実行するTemplaterのファイルを絶対パスで指定しています。環境に応じて異なると思うので、適宜書き換えてください。
次に、create_experimentを作成していきます。筆者は99-System/commands/にObsidian内で利用するすべてのTemplaterコマンドファイルを格納しているので、ここにファイルを作成していきます。
ファイルが作成できたら以下の内容を書いて保存します。
<%*
// 実験のタイトルを取得
const title = await tp.system.prompt("Enter new experiment: ")
if (!title) { return }
const dashboard_path = tp.config.active_file.path; // ボタンが押されたファイルのパスを取得
const research = await tp.file.folder(dashboard_path) // 取得したパスから研究フォルダを取得
const folder = research + "/Experiments"
const path = folder + "/" + title + ".md"
// ファイルが存在する場合はトーストを出して終了
if (await tp.file.exists(path)) {
new Notice("Warning: Experiment already exists.")
return
}
const research_template_folder = "99-System/templates/Research/"
const experiment = tp.file.find_tfile(research_template_folder + "Experiment") // テンプレートファイルを読み込む
tp.file.create_new(experiment, title, true, folder) // 第3引数を`true`にすることで作成後に開く
%>
ここでも99-System/templates/Research/というパスが登場しましたが、これは筆者が作成した研究テンプレートを格納している絶対パスです。環境に応じて適宜書き換えてください。
(実験ノートのテンプレート作成は一旦飛ばします。)
未完了実験の列挙
次に、完了していない実験を列挙するデータビューを作成していきます。
以下の内容をdataviewjsコードブロックとしてノートに埋め込みます。
let folder = dv.current().file.folder // 開かれているファイルのパスを取得
let exp_folder = '"' + folder + "/Experiments" + '"'
let experiments = dv.pages(exp_folder).where(f => f.status != "Complete").sort(f => f.created, "desc") // statusがCompleteでないものを作成日降順でソート
let keys = ["Experiment", "Status", "Started", "Ended"]
let pages = experiments.map(f => [f.file.link.withDisplay(f.file.name), f.status, f.start, f.end]) // withDisplay関数でリンクをファイル名に置き換えて表示
dv.table(keys, pages)
これで、未完了の実験が列挙されるようになりました。
Add paperボタンを作成
続けて、Add paperボタンを作成します。例のごとく、meta-bind-buttonコードブロックに以下を記述します。
style: primary
icon: circle-plus
label: "Add paper"
action:
type: "replaceSelf"
replacement: "99-System/commands/create_paper"
templater: true
今回は前のConduct experimentボタンとは異なり、typeをreplaceSelfに指定します。これは指定されたファイルの内容で自身を置き換える操作をトリガーします。今回の場合だと、このボタン自身を"99-System/commands/create_paper"のファイル内容に置き換えます。templaterのbooleanは指定されたファイルがtemplaterファイルであるかどうかを指定します。(おそらくこれをtrueにしていない場合は<%tp ~ %>が置換されないと思います)
次に、create_paperを作成していきます。ファイルが作成できたら以下の内容を順番に書いて保存します。
<%*
// 論文タイトルを取得
const title = await tp.system.prompt("Enter new paper title: ")
if (!title) { return }
const folder = "07-Researches/00-Papers/"
const path = folder + "/" + title + ".md"
// ファイルが存在する場合はトーストを出して終了
if (await tp.file.exists(path)) {
new Notice("Warning: Paper already exists.")
return
}
const research_template_folder = "99-System/templates/Research/"
const paper = tp.file.find_tfile(research_template_folder + "Paper") // テンプレートファイルを読み込み
tp.file.create_new(paper, title, true, folder) // 第3引数を`true`にすることで作成後に開く
-%>
- [[<%title%>]]
```meta-bind-button
style: primary
icon: circle-plus
label: "Add paper"
action:
type: "replaceSelf"
replacement: "99-System/commands/create_paper"
templater: true
```
一番最後の部分に先程のボタンと同じ定義が存在しています。これが重要な部分です。
こうすることでボタンを押して置換が行われたあとにもう一度ボタンを表示させることができます。(もしかしたら、もっとスマートな方法があるかもしれませんが筆者では思いつけませんでした。)
途中にある[[<%title%>]]の部分は作成した論文ノートへのリンクを作成するために記述しています。こうすることで、ダッシュボード上に各論文ノートへのリンクを自動的に作成することができます。
これで論文ノートを作成するためのボタンが作成されました。
すべての実験を列挙
ダッシュボード作成の最後に、作成したすべての実験を列挙するデータビューを作成していきます。
以下の内容をdataviewjsコードブロックとしてノートに埋め込みます。
let folder = dv.current().file.folder // 開かれているファイルのパスを取得
let exp_folder = '"' + folder + "/Experiments" + '"'
let experiments = dv.pages(exp_folder).sort(f => f.created, "desc") // 作成日降順でソート
let keys = ["Experiment", "Status", "Started", "Ended"]
let pages = experiments.map(f => [f.file.link.withDisplay(f.file.name), f.status, f.start, f.end]) // withDisplay関数でリンクをファイル名に置き換えて表示
dv.table(keys, pages)
これで、すべての実験が列挙されるようになりました。
実験ノートテンプレートを作成
次は飛ばしていた実験ノートのテンプレートを作成します。
以下の内容をファイルに保存してください。
---
created: <%tp.date.now("YYYY-MM-DD")%>
status: Not-assigned
start:
end:
---
# Objective
> [!INFO] 実験目的を端的に3行以内で
# Summary & Steps
> [!INFO] 実験内容のまとめと実験手順を書く
## Exp summary
## Steps
# Result
> [!INFO] 結果のみをここで述べる
# Consideration & Analysis
> [!INFO] なぜこのような結果が生じたのかを考察・分析する
# Reference
-
`BUTTON[set-not-assigned-task]` `BUTTON[set-in-progress-task]` `BUTTON[set-complete-task]`
### Experiment started: `INPUT[date:start]`
### Experiment ended: `INPUT[date:end]`
---
```meta-bind-button
style: primary
icon: square-x
label: "Not assigned"
id: set-not-assigned-task
hidden: true
action:
type: "updateMetadata"
bindTarget: "status"
evaluate: false
value: "Not-assigned"
```
```meta-bind-button
style: primary
icon: loader
label: "In progress"
id: set-in-progress-task
hidden: true
action:
type: "updateMetadata"
bindTarget: "status"
evaluate: false
value: "In-progress"
```
```meta-bind-button
style: primary
icon: circle-check-big
label: "Complete"
id: set-complete-task
hidden: true
action:
type: "updateMetadata"
bindTarget: "status"
evaluate: false
value: "Complete"
```
実際に押すと、入力ボックス付きのポップアップで出てくると思います。このテキストボックスに実験名を入力してEnterを押すと、実験ノートが指定されたフォルダ内に生成されるはずです。
内容ですが、最初の部分はファイルのプロパティを定義しています。これはDataviewで使用していたf.***の***部分で利用した名前を指定します。createdに関してはTemplaterで自動入力し、startとendはMarkdownの最後の部分で設定できるフィールドをINPUT[date:***]として用意しています。statusに関してはボタンで設定できるようにしています。(プルダウンを使おうかとも思ったのですが、やり方がイマイチわからなかったので断念しました。)
以上で実験ノートのテンプレート作成が完了しました。
論文ノートテンプレートを作成
最後に論文ノートのテンプレートを作成します。
以下の内容をファイルに保存してください。
---
created: <%tp.date.now("YYYY-MM-DD")%>
status: Unread
---
# Target paper
# Summary
> [!INFO] 論文の内容について端的に4行以内(スマホは8行)で書く
# Problem & Solution
> [!INFO] 課題とそれに対する解決法を書く(解決法が複数ある場合は箇条書き)
| Problem | Solution |
| ------- | -------- |
| | |
# What's new?
-
# Application & Connection
> [!NOTE] 自分の研究に活かせる点 / 繋がる部分はどこか
-
# Questions
> [!NOTE] この研究の手法や結果、実験内容等に対する疑問
-
# Reference
-
```meta-bind-button
style: primary
icon: circle-check-big
label: "Mark as read"
action:
type: "updateMetadata"
bindTarget: "status"
evaluate: false
value: "Read"
```
これも先ほどの実験ノートと同様です。ファイル冒頭でプロパティを定義して、内容を記述、ファイルの最後にstatusを変更するボタンを定義しています。
以上で論文ノートのテンプレートも完了です。
おわりに
今回は筆者がObsidianで研究ノートを管理するために生やしてしまったテンプレート群についてお話しました。何度も言うようですが、このテンプレートはまだ発展途上なので間違いや荒削りな部分が多々あります。今後、本格的に研究室での研究が始まっていくので、それに合わせてどんどんアップデートしていきたいと思います。
相変わらずの拙筆でしたが、読んでいただきありがとうございます。
それではまた次の記事でお会いしましょうノシ

