Meta
up:: ๐ฅ Sources
type:: #๐ฅ/๐ฐ
status:: #๐ฅ/๐จ
tags:: #on/plugins
topics:: Coding, Plugin - Templater
links:: ๐งช Code Diary, Plugin Hotkeys
language:: JavaScript, Plugin - Templater
How to Use Templater JS Scripts
Summary
- This is a great tutorial about the usefulness of keeping separate Plugin - Templater files instead of using them in templates themselves.
Notes
Step 1: Write .js file
async function notice(tp) {
const text = await tp.system.prompt("What's Good?")
new Notice(text, 5000)
}
module.exports = notice
Step 2: Write the Templater command
<%* tp.user.notice(tp) %>
A note on file names
it appears that Templater uses the name of the JS file and not the function name when you call the user command. I suggest naming the file the same as your exported function to avoid confusion.
Step 3: Run your new Command
Create a new note with the "Notice" template. The script prompts for input and a notification pops up with what you typed.
Breaking it down
The JS file
- We created a new function called
notice
. Whatever we set as paramters tonotice
are the arguments we provide the command. In this case, we want to run othertp
methods so we set anotice(tp)
parameter. We can include other parameters if we want. - It is an
async
function because we're doing some asynchronous JS, thusawait
it. const text = await tp.system.prompt("What's Good?")
- Because we passed in
tp
, we can use all of the available Templater command methods. In this case we are displaying a prompt.
- Because we passed in
new Notice(text, 5000)
- Since our script is running inside Obsidian we can also access the full Obsidian API. In this case we're creating a
new Notice
and displaying thetext
provided in the prompt. We can also access anything off ofapp
such asapp.vault
orapp.workspace
.
- Since our script is running inside Obsidian we can also access the full Obsidian API. In this case we're creating a
module.exports = notice
- This line is important! This is how Templater will be able to read the
notice
function we created. Just make sure to export your user function.
- This line is important! This is how Templater will be able to read the
The Templater Command
- Since we put all our logic inside the
notice.js
file, the Templater command is simple. <%* %>
- This particular command does not have any output, thats why we use the
*
instead of<% %>
. If we want to return something from our JS file, we could use the standard Templater syntax.
- This particular command does not have any output, thats why we use the
tp.user.notice(tp)
- This is calling the function we created in
notice.js
. Two things to note here:- All user specified functions will be under
tp.user
- Remember how we specified
notice(tp)
parameter when writing thenotice
function? We're supplyingtp
as an argument when calling the function. We could supply additional arguments if our JS function required them.
- All user specified functions will be under
- This is calling the function we created in
Advanced Usage
- Let's take a command that creates a new block-reference:
<%*
let cmEditorAct = this.app.workspace.activeLeaf.view.sourceMode.cmEditor;
let curLine = cmEditorAct.getCursor().line;
cmEditorAct.setSelection({ line: curLine, ch: 0 }, { line: curLine, ch: 9999 });
function createBlockHash() {
let result = '';
var characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < 7; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
let id = createBlockHash();
let block = ![[${tp.file.title}#^${id}]].split("\n").join("");
navigator.clipboard.writeText(block).then(text => text);
tR = tp.file.selection() + ^${id}.split("\n").join("");
%>
- And convert it into a JS file + Command.
- The JS File: (this goes in the Templater Scripts folder)
function addBlockRef(tp) {
//Use the Obsidian API to get the CodeMirror Editor
const editor = app.workspace.activeLeaf.view.editor
const cursorLine = editor.getCursor().line
//Set the selection in the CodeMirror Editor
editor.setSelection({line: cursorLine, ch: 0}, {line: cursorLine, ch: 9999})
const id = createBlockHash();
const block = `![[${tp.file.title}#^${id}]]`.split("\n").join("");
// Copy the block reference to the clipboard
navigator.clipboard.writeText(block).then(text => text);
//Return the selected text and the generated block id
return tp.file.selection() + `^${id}`.split("\n").join("");
}
//A simple function to create a random block id
function createBlockHash() {
let result = '';
var characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for ( var i = 0; i < 7; i++ ) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
//export the addBlockRef function
module.exports = addBlockRef
- The Templater Command: (this goes in your template file)
<% tp.user.addBlockRef(tp) %>
Ideas
- I could use this functionality to create cleaner, modular templates.
- For example, each type of source has it's own Metadata, can I separate these using a script?
up:: Plugin - Templater