Templater icon indicating copy to clipboard operation
Templater copied to clipboard

Frontmatter not finding right value

Open Tricksturdoesstuff opened this issue 2 years ago • 8 comments

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.

Tricksturdoesstuff avatar Nov 21 '21 06:11 Tricksturdoesstuff

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?

Tricksturdoesstuff avatar Nov 21 '21 06:11 Tricksturdoesstuff

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]
%>

shabegom avatar Jan 13 '22 13:01 shabegom

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

ghost avatar Jan 16 '22 21:01 ghost

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

GamerGirlandCo avatar Jul 18 '22 18:07 GamerGirlandCo

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.

AB1908 avatar Jul 18 '22 19:07 AB1908

If you give us a description of your use case, we might be able to give you other ideas.

AB1908 avatar Jul 18 '22 19:07 AB1908

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.

GamerGirlandCo avatar Jul 18 '22 19:07 GamerGirlandCo

Hmm I think some QuickAddJS may be a better fit here. tp.file.frontmatter won't work inside that.

AB1908 avatar Jul 18 '22 19:07 AB1908