Templater
Templater copied to clipboard
Frontmatter not finding right value
Plugin informations (please complete the following information):
- OS: Windows 10
- Templater version: 1.9.9
- Obsidian version: 0.13.4
- Templater settings: location: Templates/
Input:
---
format: note
---
<% tp.frontmatter.format %>
Output:
---
format: note
---
undefined`
Describe the bug I'm trying to call frontmatter but all it ever does is give me undefined. I've tried various versions of spacing or capitalization or numbers of colons.
Expected behavior It should be saying note, not undefined.
Screenshots If applicable, add screenshots to help explain your problem.
Additional context
I've tried this in a number of vaults with various settings. Somebody on discord tried the same code, and it worked on theirs. I'm not sure what I'm doing wrong.
Also I should add other commands such as <% tp.file.title %>
are working.
Oh, I've figured out some additional behavior, but I'm not sure how to get around this if I'm using it as a template...
If I just add a template underneath the YAML it will pick it up. If I either create a new note or insert into an empty note, it can't detect the YAML frontmatter.
Is there anyway around this? Do I always have to have the YAML on top ready to go first before I can insert the reference to it?
This is a caching problem. Templater is trying to get the frontmatter values before obsidian has had a chance to index/cache them. A workaround would be to read the value directly from the notes contents. Something like:
<% tp.file.content.split("\n").filter(line => line.includes("format: "))[0].split(": ")[1]
%>
I found another workaround by referencing the frontmatter function's code. The following example template allows you to parse the template's frontmatter, rather than the frontmatter of the target file.
---
alias: 'foobar'
foo: 'bar'
date: '<% tp.date.now() %>'
---
<%*
const template_cache = this.app.metadataCache.getFileCache(
tp.config.template_file
);
var frontmatter = template_cache?.frontmatter || {};
_%>
<% frontmatter.alias %>
<% frontmatter.foo %>
<% frontmatter.date %>
Produces the following template.
---
alias: 'foobar'
foo: 'bar'
date: '2022-01-16'
---
foobar
bar
2022-01-16
I found another workaround by referencing the frontmatter function's code. The following example template allows you to parse the template's frontmatter, rather than the frontmatter of the target file.
--- alias: 'foobar' foo: 'bar' date: '<% tp.date.now() %>' --- <%* const template_cache = this.app.metadataCache.getFileCache( tp.config.template_file ); var frontmatter = template_cache?.frontmatter || {}; _%> <% frontmatter.alias %> <% frontmatter.foo %> <% frontmatter.date %>
this doesn't work if you move
<% frontmatter.alias %>
<% frontmatter.foo %>
<% frontmatter.date %>
into the frontmatter section :/ frontmatter
remains undefined
.
edit
it doesn't work if you move it out of the frontmatter section either. console.log
-ing the frontmatter
variable returns undefined
Are these contents in your template? If so, preferably store in variables and reuse as otherwise you'd have to wait for metadataCache to update.
If you give us a description of your use case, we might be able to give you other ideas.
If you give us a description of your use case, we might be able to give you other ideas.
what i'm trying to do is use Templater in conjunction with the QuickAdd plugin, which supports using templater templates to create files.
i'm trying to conditionally add a yaml property based on the value of another yaml property, like so:
---
title: {{VALUE:title}}
type: {{VALUE:type}}
<%*
if(tp.frontmatter.type.toLowerCase() === "value") {
tR += "{{VALUE:ot}}"
}
-%>
---
note that {{VALUE:<...>}}
is parsed according to QuickAdd's internal syntax prior to the file being ran through Templater.
Hmm I think some QuickAddJS may be a better fit here. tp.file.frontmatter
won't work inside that.