Templater
Templater copied to clipboard
Allow tp.frontmatter module to work on file creation
Plugin information (please complete the following information):
- OS: Linux
- Templater version: 2.1.0
- Obsidian version: 1.5.3
- Templater settings: folder location is
templates
. I don't think anything else is relevant.
Describe the bug When a template is executed, the functions are invoked bottom-to-top instead of top-to-bottom. This is counter-intuitive, and can cause issues.
For example, I want to set the note title, and other frontmatter, then use that information later in the note for use by other functions. However, this won't work as the frontmatter is set after everything else.
Expected behavior Functions should be invoked top-to-bottom, so that frontmatter is set before everything else.
Additional context
---
title: 2024-01-01
weekday: <% tp.date.now("dddd", 0, tp.file.title) %>
creation date: <% tp.file.creation_date() %>
modified date: <% tp.file.creation_date('YYYY-MM-DD HH:mm:ss') %>
---
<%* if (tp.frontmatter.weekday == "Wednesday") { -%>
Do this
<%* } -%>
The above code will not be executed correctly, as the function setting the frontmatter weekday has not been run yet. I'm trying to do it this way because it follows the DRY approach to programming. I don't want to write the function to get the current date every time I want to use it in an operation.
I don't think tp.frontmatter
is really meant to be used this way, on file creation 🤔 ... but much more to get existing frontmatters (already cached somewhere) when updating a note or something...
The example in the documentation for tp.frontmatter
uses hardcoded/static YAML "already there"... So, that's how I understand it 😅 (as I've actually never used tp.frontmatter
)
I mean, after some testing, I think that by the time tp.frontmatter
runs, whether you await
it or not in the template you shared, Obsidian just didn't register the creation of the frontmatter weekday
which lead to Templater not being able to use it in the same template... (tp.frontmatter.weekday
returning undefined
in any cases).
I've used console.log()
to check in the Dev tool in what order the template was read and applied:
<% "---" %>
<%* console.log(1) -%>
title: <% tp.file.title %>
<%* console.log(2) -%>
weekday: <% tp.date.now("dddd", 0, tp.file.title, "YYYY-MM-DD") %>
<%* console.log(3) -%>
creation date: <% tp.file.creation_date() %>
<%* console.log(4) -%>
modified date: <% tp.file.creation_date('YYYY-MM-DD HH:mm:ss') %>
<% "---" %>
<%*
console.log(5)
if (tp.frontmatter.weekday === "Wednesday") {
console.log(6);
tR += "Do this";
} else {
console.log(7);
tR += "Do that";
}
-%>
And the console replied with:
... hence why I ended up thinking it's a cache issue more than anything else 😊.
(
if
returning false
because tp.frontmatter.weekday
is undefined
)
Another test would be: if you apply, to a note titled 2024-01-03
, a template such as:
<% "---" %>
title: 2024-01-03
weekday: <% tp.date.now("dddd", 0, tp.file.title, "YYYY-MM-DD") %>
creation date: <% tp.file.creation_date() %>
modified date: <% tp.file.creation_date('YYYY-MM-DD HH:mm:ss') %>
<% "---" %>
... resulting in:
---
title: 2024-01-03
weekday: Wednesday
creation date: 2024-01-09 12:30
modified date: 2024-01-09 12:30:11
---
and then apply on the same note a template such as:
<%*
if (tp.frontmatter.weekday === "Wednesday") {
tR += "Do this"
} else {
tR += "Do that"
}
-%>
... it will then output : Do this
in the note 2024-01-03
.
(tp.frontmatter.weekday
now being cached by Obsidian between the 2 template applications and returning as expected Wednesday
)
A way to bypass the probable Obsidian cache thingy going on here could be to declare constants/variables and re-use them where needed. E.g.:
<%*
const title = tp.file.title;
let weekday = tp.date.now("dddd", 0, title, "YYYY-MM-DD");
let created = tp.file.creation_date();
let modified = tp.file.creation_date('YYYY-MM-DD HH:mm:ss');
-%>
<% "---" %>
title: <% title %>
weekday: <% weekday %>
creation date: <% created %>
modified date: <% modified %>
<% "---" %>
<%*
if (weekday === "Wednesday") {
tR += "Do this"
} else {
tR += "Do that"
}
-%>
... in which <% weekday %>
and the weekday
in the if
are both the value returned by the let weekday...
at the top:
// ...
let weekday = tp.date.now("dddd", 0, title, "YYYY-MM-DD");
// ...
Which when applied to a note titled 2024-01-03
returns, in one go:
---
title: 2024-01-03
weekday: Wednesday
creation date: 2024-01-09 12:30
modified date: 2024-01-09 12:30:11
---
Do this