## 概要
[[フロントマター]]の特定キーを今日の日付で更新したい。`updated`など。
## ソリューション
[[Templater]]を使って以下のスクリプトを作成します。
```js
<%*
// Front matterのキー
const KEY = 'updated'
// 値の日時フォーマット
const date = tp.date.now("YYYY-MM-DD")
const UPDATED = `${KEY}: ${date}`
const editor = app.workspace.activeLeaf.view.editor
const updatedFrontMatter = tp.frontmatter.updated
if (updatedFrontMatter) {
const index = await tp.user.replace_line_at_word_starts(KEY + ": ", UPDATED)
if (index !== undefined) {
new Notice("最終更新日を更新しました")
} else {
new Notice("最終更新日を更新しようとしましたが失敗しました")
}
return
}
const frontMatterBody = `
created: ${date}
updated: ${date}
`.trim()
const hasFrontMatter = Object.keys(tp.frontmatter).length > 0
if (hasFrontMatter) {
await tp.user.insert_new_line_at_word_found("---", frontMatterBody)
return
}
const noteBody = `---
${frontMatterBody}
---
`
await tp.user.insert_new_line_at_first(noteBody)
%>
```
`tp.user.insert_new_line_at_word_found`と`tp.user.insert_new_line_at_first`はユーザースクリプトとしてそれぞれ定義します。
> [!code]- insert_new_line_at_word_found.js
>
> ```js
> /**
> * 指定された文字列と一致する行の次の行にテキストを追加する
> * @param {string} query
> * @param {string} text
> *
> * @returns {Promise<number | undefined>} 挿入した行index (未挿入ならundefined)
> */
> async function insertNewLineAtWordFound(query, text) {
> const editor = app.workspace.activeLeaf.view.editor;
>
> let rowIndexFound = -1;
> for (let row = 0; row <= editor.lastLine(); row++) {
> if (editor.getLine(row) === query) {
> rowIndexFound = row;
> break;
> }
> }
>
> if (rowIndexFound !== -1) {
> editor.replaceRange("\n" + text, CodeMirror.Pos(rowIndexFound));
> }
>
> return rowIndexFound === -1 ? undefined : rowIndexFound + 1;
> }
>
> module.exports = insertNewLineAtWordFound;
> ```
> [!code]- insert_new_line_at_first.js
>
> ```js
> /**
> * 一番上の行にテキストを追加する
> * @param {*} text
> */
> async function insertNewLineAtFirst(text) {
> const editor = app.workspace.activeLeaf.view.editor;
> editor.replaceRange(text, CodeMirror.Pos(-1));
> }
>
> module.exports = insertNewLineAtFirst;
> ```
>
> [!code]- replace_line_at_word_starts.js
>
> ```js
> /**
> * 指定された文字列と前方一致する行を置換する
> * @param {string} query
> * @param {string} text
> *
> * @returns {Promise<number | undefined>} ちかんした行index (未挿入ならundefined)
> */
> async function replaceLineAtWordStarts(query, text) {
> const editor = app.workspace.activeLeaf.view.editor;
>
> let rowIndexFound = -1;
> for (let row = 0; row <= editor.lastLine(); row++) {
> if (editor.getLine(row).startsWith(query)) {
> rowIndexFound = row;
> break;
> }
> }
>
> if (rowIndexFound !== -1) {
> editor.replaceRange(
> text,
> { line: rowIndexFound, ch: 0 },
> { line: rowIndexFound }
> );
> }
>
> return rowIndexFound === -1 ? undefined : rowIndexFound;
> }
>
> module.exports = replaceLineAtWordStarts;
> ```
### スクリプトの挙動
- [[フロントマター]]が存在しないとき
- [[フロントマター]]および`created`と`updated`が追加されます
- [[フロントマター]]は存在するが、`updated`のキーが存在しないとき
- [[フロントマター]]の最上部に`created`と`updated`が追加されます
- [[フロントマター]]が存在して、`updated`のキーも存在するとき
- `updated`の値が今日の日付で更新されます
> [!info] コマンドにホットキーを登録する方法
> [[Templaterで作成したコマンド(スクリプト)をホットキーで実行する方法]] を参考にしてください。