New Properties and templater prompts and commands?

Hi there,

is there a way to make the new props view work with templater prompts and commands? Most of my templates have prompts and commands to set some YAML.

Cheers, H.

3 Likes

I’m having the same issue.

1 Like

Same problem. What’s more there doesn’t seem to be a mode to treat front matter like plain text anymore.

1 Like

Likewise, specifically my command for setting the file’s creation date just results in a blank Created property.

1 Like

In Nicole’s video on Obsidian Properties, she notes that a property with a format such as Date will conflict with a Template/Templater file that has code in that property. I’m unaware if there is a workaround or solution to this and I’m surprised there have been no further posts here. Perhaps I’ve missed something in a subsequent update?

The video: https://youtu.be/RrxqkIhh9L8

As someone coming into Templater mostly after the Properties update, I’ve made most of my entire Templatery frontmatter be generated with a large Templater execute block. For instance, instead of doing:

---
tags: <% tp.system.prompt("Which tag?") %>
date: <% tp.date.now %>
---

I’ve been doing this:

<%*
tR += "---" + "\n"

let tag = await tp.system.prompt("Which tag?")
tR += "tags: " + tag + "\n"

let date = tp.date.now
tR += "date: " + date + "\n"
tR += "---"
%>

Properties can’t pre-format your metadata and escape your Templater actions if there’s no metadata until Templater has gone through all of its steps. It’s a lot more Javascript, but it works, until they figure out how to make Templater and Properties play nice.

I also usually assign a much nicer constant to the “/n” command like “newLine”, and comment the heck out of the entire thing so it’s more readable. It’s not ideal, but like I said, it works.

5 Likes

You can also write/apply the YAML dashes (---) through Templater like this :

Credits to Zachatoo :blush: : Escaping frontmatter in a template.

Edit: Thinking about this, you could probably also write your template :

Like this :

<%*
let tag = await tp.system.prompt("Which tag?");
let date = tp.date.now('YYYY-MM-DD');
_%>
<%"---"%>
tags: <% tag %>
date: <% date %>
<%"---"%>
9 Likes

But this requires you to write your full frontmatter in the template each time, right? I know it may not be that big a deal, given it is a template, but I would really like to be able to just request a value for a property and add it to the existing lay-out. But I see that I might have to re-think my template design.

1 Like

@Schollert add this to any template to change a single field(s):

<%*
setTimeout(() => {
  app.fileManager.processFrontMatter(tp.config.target_file, frontmatter => {

    // Update or add as many fields as you want
    frontmatter['Some property'] = 'Some value'
    frontmatter['Another property'] = 'Some other value'

    // You can even remove properties if you want
    delete frontmatter['Unwanted property']

  })
}, 200) // the reason for the timeout is to let the template complete first
-%>

No need to re-think your template design.

23 Likes

Wow - cool! Thank you very much!!

1 Like

Spent the better part of yesterday down the rabbit hole of frontmatter and Templater and MetaEdit and all sorts of other things trying to do something that, in theory, should have been really simple.

Of course I came across this at the end instead of the beginning…

Not entirely a waste - ended up writing a JS function to parse geo data from Google Places into address/street/province/description frontmatter fields and then insert a Leaflet map. Once I came across your post it was a five minute bolt up.

Could have asked I suppose but the spelunking is half the fun.

Much appreciated!

2 Likes

Just a small/final update from my side. With your input I managed to get my template to ask for title and two tags (category and subject) and place the information correct. Great fun fiddling with it to understand how things work.

I leave the code here, in case other want to so something similar.

<%* 
let title = tp.file.title 
let sSubject = ""
let sCategory = ""

if (title.startsWith("Untitled")) { 
  title = await tp.system.prompt("Title"); 
} await tp.file.rename(title);

sCategory = await tp.system.prompt("Category");
sSubject = await tp.system.prompt("Subject");

setTimeout(() => {
  app.fileManager.processFrontMatter(tp.config.target_file, frontmatter => {
  frontmatter["category"] = sCategory;
  frontmatter["subject"] = sSubject;
  })
}, 200)

-%>
9 Likes

I do the following:

---
KEYs: VALUEs for the template
---

<%_* tR += "" _%>

---
KEYs: VALUEs for the new note based on the template
---

CONTENT

The <%_* tR += "" _%> deletes everything collected until that point of execution.

Nicely formatted and easier to write. :wink:

Hey, Alan,

Last time I incorporated your solution in a longer Templater Js script and it threw the usual merging issues pop-up on me (and added false field values as well, ostensibly because of timing issues in my script).
Used the MetaEdit way instead:

// Using the MetaEdit API's createYamlProperty function add the 'class' property with the value 'dg_uploaded'
const { createYamlProperty } = this.app.plugins.plugins["metaedit"].api;
const classPropertyName = 'class';
await createYamlProperty(classPropertyName, 'dg_uploaded', currentFile);
console.log("Added 'class' property with value 'dg_uploaded' in the current file.");

If anybody wants to use this, let me remind them that currently adding only a single property works reliably in MetaEdit. (See here.)

EDIT. Turns out this doesn’t work very well, either. Dang, these timing issues and then messing up and correcting YAML keys and values really cut into my days…

EDIT 2.
If adding single or multiple properties draws errors (because everybody’s scripts are different and note lengths can vary, not to mention CPU speed differences or other quirks), one very strange-sounding workaround would be to batch-create a dummy_key: dummy field line (or two) in every file using an outside of Obsidian search and replace method (like the one discussed here), then in the templater script we search and replace those dummies on demand, like so:

  // Replace some fields
  updatedContent = updatedContent.replace(/dg_upload_status:\sdown/g, 'class: dg_uploaded');
  updatedContent = updatedContent.replace(/unformatted⚪/g, 'formatted🟢');
2 Likes

this is great - thank you!

1 Like

Hi, thanks for that but… I have tried changing only one property called Parent and it has eliminated the rest of the property as well as everything that that template has in addition

This is my code:

<%*
  app.fileManager.processFrontMatter(tp.config.target_file, frontmatter => {

    // Update or add as many fields as you want
   frontmatter['father'] = 'hi'

  })

-%>

Thanks!!!

I’ve been using Zachatoo’s “Update frontmatter” snippet tailored to my need without any issue of this kind so far :thinking: …

Maybe you could try something like:

<%*
const file = tp.file.find_tfile(tp.file.path(true));
await app.fileManager.processFrontMatter(file, (frontmatter) => {
  // Update or create key "father"
  frontmatter["father"] = "Hi!";
  // Update or create key "son"
  frontmatter["son"] = "Hey there...";
  // Delete key "mother" (if present)
  delete frontmatter["mother"];
})
-%>

I’ve tested this on a note with the following content:

---
father: 
mother:
---
## Lorem Ipsum

> "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."
> "There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum efficitur vel magna nec rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac nibh nec eros sollicitudin viverra. Sed porttitor pretium molestie. Integer viverra turpis orci, et semper justo tempus sed. Sed non porta lorem, sed venenatis elit. Proin diam dui, pulvinar vitae egestas ac, dictum a magna. Praesent tincidunt augue vel nunc aliquam, eu pharetra diam finibus. In placerat est ut lorem dignissim commodo. Aenean vulputate lectus a dapibus tincidunt.

Aenean at condimentum neque, ullamcorper efficitur dui. Integer lacinia arcu ac rhoncus convallis. Morbi nunc lacus, ullamcorper at hendrerit at, ultrices in nisi. Ut elementum dignissim condimentum. Curabitur tortor est, molestie non accumsan vitae, congue ut ex. Aenean sed nibh enim. Maecenas eu eros commodo, volutpat quam nec, pharetra odio. Suspendisse imperdiet aliquet dolor, a faucibus nisi varius vel. Ut molestie dapibus lobortis. Fusce quis dui elit. Vivamus rutrum iaculis sagittis. Etiam venenatis felis ut mauris egestas, sit amet dictum eros rhoncus. Suspendisse eget magna quis magna accumsan maximus eget vel ipsum. Fusce dictum faucibus neque, eu pharetra sem sagittis ornare.

and ended up with:

---
father: Hi!
son: Hey there...
---
## Lorem Ipsum

> "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."
> "There is no one who loves pain itself, who seeks after it and wants to have it, simply because it is pain..."

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum efficitur vel magna nec rutrum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ac nibh nec eros sollicitudin viverra. Sed porttitor pretium molestie. Integer viverra turpis orci, et semper justo tempus sed. Sed non porta lorem, sed venenatis elit. Proin diam dui, pulvinar vitae egestas ac, dictum a magna. Praesent tincidunt augue vel nunc aliquam, eu pharetra diam finibus. In placerat est ut lorem dignissim commodo. Aenean vulputate lectus a dapibus tincidunt.

Aenean at condimentum neque, ullamcorper efficitur dui. Integer lacinia arcu ac rhoncus convallis. Morbi nunc lacus, ullamcorper at hendrerit at, ultrices in nisi. Ut elementum dignissim condimentum. Curabitur tortor est, molestie non accumsan vitae, congue ut ex. Aenean sed nibh enim. Maecenas eu eros commodo, volutpat quam nec, pharetra odio. Suspendisse imperdiet aliquet dolor, a faucibus nisi varius vel. Ut molestie dapibus lobortis. Fusce quis dui elit. Vivamus rutrum iaculis sagittis. Etiam venenatis felis ut mauris egestas, sit amet dictum eros rhoncus. Suspendisse eget magna quis magna accumsan maximus eget vel ipsum. Fusce dictum faucibus neque, eu pharetra sem sagittis ornare.

Update key

1 Like

Thanks but… this is my result:
CleanShot-2024-01-05-at-08.25.42

Could it be something in the configuration or what could be happening to make Obsidian act like this?

Thank you very much again

Processing the frontmatter of the current file can be icky, and is usually best done using a setTimeout() call to processFrontMatter(), this to avoid race conditions on who edits the file: You, the template or processFrontMatter().

I’m on mobile now, but there are multiple examples here in the forum for the syntax.

Thanks but… same problem :sob:

<%*
const file = tp.file.find_tfile(tp.file.path(true));

setTimeout(() => { 
app.fileManager.processFrontMatter(file, (frontmatter) => {
  // Update or create key "father"
  frontmatter["father"] = "Hi!";
  // Update or create key "son"
  frontmatter["son"] = "Hey there...";
  // Delete key "mother" (if present)
  delete frontmatter["mother"];
}) }, 200)
-%>

I see something strange, if I write something in the new note before applying the template then what I have in the template appears but the parameters I have in the template no longer pass as parameters but as text.

CleanShot-2024-01-05-at-08.25.42