Help with inheritence of yaml, or how to create child note

Hi there,

I need some help with the following templater code, but first I’ll describe shortly my use case:
I want to create “insight notes” out of my “source notes” and I want, that my “insight notes” inherit all the yaml of the “source note” it originates from (“source note” = “parent note” and “insight note” = “child note”).

The following templater code is heavily inspired by this thread and the solution of @holroy :

<%*
const dv = this.app.plugins.plugins["dataview"].api

const curr = tp.config.target_file
const dvCurr = dv.page( curr.path )
const baseFolder = app.vault.getAbstractFileByPath(dvCurr.file.folder)


const newFile = await tp.system.prompt("New file name")

const content = 
`---
tags:
  - note/insight 
property1: ${ tp.frontmatter["property1"] }
property2: ${ tp.frontmatter["property2"] }
property3: ${ tp.frontmatter["property3"] }
parent_note: "[[${ dvCurr.file.name }]]"
---

`
/* 
console.log("Content", content)
console.log(curr)
console.log( dv.page(curr.path) )
*/

await tp.file.create_new(content, newFile, true, baseFolder)

_%>

Pressing Strg + P => “open insert template modal” inside my source note out of which I want to create a new insight note works nearly perfectly fine, but:
If one of the inherited properties is of type list, e.g.:

property1:
  - value1
  - value2

in the new insight note, these values will be written in this wrong format:

property1: value1, value2 

which will return an error inside Obsidian.

So my question is: How do I have to modify the templater script, to get propper yaml in my insight notes :slight_smile:

Thanks in advance,
kind regards,

Silias

Hi again, here is one variant on how to do something like this. It’s not extensively tested, but it seems to work nicely in the few tests I did run.

<%*
const dv = this.app.plugins.plugins["dataview"].api

const curr = tp.config.target_file
const dvCurr = dv.page( curr.path )
const baseFolder = app.vault.getAbstractFileByPath(dvCurr.file.folder)


const newFile = await tp.system.prompt("New file name")
const propertyList = [ "property1", "property2", "property3" ]

// Lets build the content in bits and pieces
let content = `---\ntags:\n - note/insight\n`

// Loop through each of the properties we want
// to copy into the new note
for (const prop of propertyList) {
  if ( typeof(tp.frontmatter[prop]) == "string" ) {
    content += prop + ": " + tp.frontmatter[prop] + "\n"
  } else {
    content += prop + ": \n"
    for (const item of tp.frontmatter[prop]) {
      content += "- " + JSON.stringify(item) + "\n"
    }
  }
}

// Add the origin of the content
content += `parent_note: "[[${ dvCurr.file.name }]]"\n---\n\n`

/* 
console.log("Content", content)
console.log(curr)
console.log( dv.page(curr.path) )
*/

await tp.file.create_new(content, newFile, true, baseFolder)
_%>

The trick it relies on is building the content step by step, and then detecting whether we’ve got a single string property or an object. And in the latter case it’ll use the JSON.stringify() on each item in that list (given it’s a list… :slight_smile: ) to make it a valid property.

This does leave some extra quotes around the strings in the pure list case, but that could potentially be avoided by doing more type checks before outputting within the for loop.

1 Like

Thanks for this nice piece of code! :slight_smile:

Unfortunately I get an error, trying to execute it. … As I’m still not able to log to the console (how I described here), I don’t know how to find out, which part of your code is causing problems in my setup… Do you have any further advice for me?