Templater templates

Published on:2024/12/10
Banner for Templater templates

Introduction

This is not article as much as it is a live document of snippets I use with the Templater plugin for Obsidian.

While QuickAdd is the easiest gate to the Obsidian API right now, I use Templater as an "editor API" where each macro is most likely a convenient shortcut to be rewritten in different language for a different editor (say lua and neovim) than it is to be called remotely.

The main reasons for this is Templater's streamlined approach to modifying and referencing the current file (by opposition to creating a new one).

Templater also auto register new files in a certain folder as new macro and registering said macro as a new command in the palette is far more straight forward than QuickAdd's.

The trade-off being Templater is mostly unable to really layer macros.

Consider each of the following snippet to have to run in markdown file within <%* and %>.

Snippets

Get TFile from current object

Maybe the most important bit

let file = tp.file.find_tfile(tp.file.title);

Modifying the fronmatter

await tp.app.fileManager.processFrontMatter(file,
	(frontmatter) => {
	frontmatter.this = "not that";
	});

User choice

const status = await tp.system.suggester(["todo","mark"],["/", "!"] );

Hard coded dataview query

This is particularly useful to "freeze" the result of a query on a given day

const queryResult = dv.pages('#project').map(p => ({ title: p.file.name, status: p.status, dueDate: p.dueDate }));

Build the table

const headers = ["Title", "Status", "Due Date"];
let tableContent = `| ${headers.join(" | ")} |\n`;
tableContent += `| ${headers.map(() => "---").join(" | ")} |\n`;

// Add rows to the table, with the title as a link to that note
queryResult.forEach(item => {
    const linkTitle = `[[${item.title}]]`; // Create an internal link
    tableContent += `| ${linkTitle} | ${item.status} | ${item.dueDate} |\n`;
});

Add the content

Simply call the vairbale somewhere in the template:

<% tableContent %>

Clipboard

Both methods can be paired with the processFrontMatter function to achieve functionality similar to emacs's org-insert and org-store.

Writing

let file = tp.file.find_tfile(tp.file.title); // Get current TFile
navigator.clipboard.writeText(file.id);

Reading

let xclip = tp.system.clipboard() // Get clipboard here
let dv = app.plugins.plugins.dataview.api //Get dataview api instance
let prevousFile = dv.page(xclip); // find the file associated with the UUID in clipboard
let file = tp.file.find_tfile(tp.file.title);
await tp.app.fileManager.processFrontMatter(file, // Then add the value in frontmatter as a link in the someField field
	(frontmatter) => {
	frontmatter.someField = `[${previousFile.path}|${previousFile.title}]`;
	});