Hi everyone, I would like to share some Obsidian Templater code on how you can create a new note/file based on existing frontmatter template file and then autocomplete (modify) properties of the frontmatter in the newly created note.
The whole idea here is to keep separate your Templater code from the frontmatter template file otherwise you have to include the frontmatter with some trick so that Obsidian treats frontmatter information as regular text instead of recognizing frontmatter properties.
For the Templater newcomer, I have been there myself and spent a lot of time, there is also the problem of how you trigger the Tempater code so that it creates your new note/file based on it (i.e. Templater: Create new note from template
command, or Alt+N
or click the <%
templater symbol at the ribbon).
In that case you must not use tp.file.create_new
in your code because that will create an extra Untitled
file inside the folder which you do not want. Instead I use tp.file.rename
to change the Untitled
filename of the new file and then tp.file.include
to include my frontmatter type inside the new file.
Finally in order to modify the frontmatter, e.g. autocomplete properties or add new properties, you have to use tp.hooks.on_all_templates_executed
. This way the file will be created with the specific frontmatter and then it will be modified.
Attention: If you try to trigger the Templater code when your cursor is at the current opened file, your new file/note is created on the same folder with the current note, it is opened and it becomes the new current note.
An alternative is to right-click on the folder you want to create your note/file and run the Templater: Create new note from template
command. But again it is opened in the same tab with the previous current note and it becomes the new current note.
There is also a quicker way to create the new note/file by adding a new Folder Template
in Templater configuration.
Advantage of using this method
You can add content after your Templater code and include javascript variables and frontmatter properties. For example I have added a Meta-Bind plugin INPUT
box.
My frontmatter type (Note.type)
---
tags:
- type/note
title:
description:
url:
publish: false
---
My templater code
<%*
const ext = ".note"
const typefilename = "Note.type"
// Rename NEW Untitled file
const filename = tp.date.now("YYYYMMDD")+moment().format('HHmmss')+ext
await tp.file.rename(filename);
// Include frontmatter properties from the <.type> file
const type = await tp.file.find_tfile(typefilename);
tR += await tp.file.include(type);
// Modify frontmatter by adding created_at and updated_at properties
tp.hooks.on_all_templates_executed(async () => {
// construct timestamp
const dfrmt = "YYYY-MM-DD" ;
const tfrmt = "HH:mm:ss" ;
const zfrmt = "+03:00" ;
var timestamp = tp.date.now(dfrmt)+"T"+moment().format(tfrmt)+zfrmt ;
const file = tp.file.find_tfile(filename);
await app.fileManager.processFrontMatter(file, (frontmatter) => {
frontmatter["created_at"] = timestamp;
frontmatter["updated_at"] = timestamp;
});
});
%>
`INPUT[text:description]`
Many thanks to all Obsidian and Templater developers and contributors, stay tuned.
References
Templater: Trigger Templater on new file creation
Trying to get a Templatr template to move new files to a folder based on front matter