How to create a new note with passed metadata in the header?

I’m wondering what are the different paths to create a new note or page, from a generated link. I would like the new note to have some metadata upon creation. Specifically for me, I would like to include the name/path of the page holding the creation-link.

For example:

Page A:

blah blah to [[Footnotes for this author]] will illuminate…

Page Footnotes for this author:

outlinks: Page A

The goal seems similar to this post, but I can’t figure out how to get that workflow, and there may be other ways to do it, anyway. I am coming from a dataviewjs-generated table, so I could in principle script something.

Are you using Templater for creating the new file?

Given Templater you can access the originating file through tp.config.active_file, and then use stuff from that in your new file.


Thanks holroy!

I paste here my script, working and probably a little verbose. I also paste a screencapture to show what does what, in case someone else has a similar wish and can adapt this.


When I am reading historical sources, I come across dates of events. I want to collect them, but very quickly. So I have a template that can parse what is fast for me to type:

label:: Legislation passed on ...

After I select that text, I press hotkeys to run a template. That template will create a new file with a unique name (date with seconds)
and indicate it’s a “timeline_item” in my system. I want to keep track which Obsidian note is the “parent” note, or “source” note.

I haven’t decided if I want to put information in the YAML header or in the body of the new to-be-created-note. So in the script below. I put it in both places. Single colon in the YAML header and double colon in the body of the to-be-created-note.

I also want all the “timeline_items” to be collected into a separate folder. That is hard-coded in my script.

And in the parent document, after I run this template, I want to:
wrap the selected text to enclose it in backticks ```, to quickly give me a visual
indication that these name-value pairs have been turned into a timeline_item.

And I make a link from the parent note to the just-created-note with an aliased “TL”.

I pasted a screenshot too, below. It’s a bit messy, but perhaps useful.

/* */

let my_content = tp.file.selection();
let my_source_note = tp.file.title;
/* somehow these three are the same: (which confuses me) */
/* 1) 2)
/* and 3) tp.file.title point to the parent document */

if (my_content) {
	newfilename ="YYYYMMDD-hhmmss") + "_timeline_item";

	tp.file.create_new("---\nsource-note:\"" +  my_source_note + "\"\n---\n"
	+ my_content + "\n"
	+ "source-note:: [[" + my_source_note + "]]",
	newfilename, false, app.vault.getAbstractFileByPath("Delta-Mississippi/timeline_items") );

	tR = "```\n" + tp.file.selection() +  "\n```" +  " \n" + "[[" + newfilename + "|TL]]"
1 Like

So glad, you found a way to do this as you like it!

Just a few comments related to your script:

  • Not entirely sure about those three variants of the file name, but I reckon they come into play depending on you trigger the template. Now you trigger to a hotkey from within the same file. Another option could be to create new file (from another file). Another option is to create the new file (with a template) from within another template. So these will most likely trigger some variation in these variables
  • I’m not quite sure whether I would actually put the timeline items in a separate file, or just rely on querying them whenever needed. (But then again, I’m not quite certain I see the pros and cons of how you like to use them either. :slight_smile: )
  • Whenever you do stuff with files, like tp.file.create_new() (or renaming/moving/… ) it’s better to add await in front of it, so it is written as await tp.file.create_new( ... ). I could explain it, but the gist is that file operations take time, and doing await ensure that it’s finished before you move on with your script
  • I would also, most likely, move out the generation of the new content into a const new_content = ... , so that the function call to create_new() is cleaner, and not so cluttered up

Lastly, I’ve never been a fan of adding strings together using +. This is a matter of personal preference and taste, but I would much rather write your long string concatenation as something like:

const new_content = `\
source-note: "${ my_source_note }"
source-note:: [[${ my_content }]]

// and
tR = `\
${ tp.file.selection() }
[[ ${ newfilename } | TL ]]

Two notes related to this syntax:

  • The start with `\, is just syntactic sugar, to really get the view of the new string. You could if you feel like it start with the `---, but I kind of like this variant better
  • Instead of doing the \`\`\` , I opted for using the equivalent code fence of ~~~.

One final thing: When you’ve got a note name in the frontmatter (or in code blocks) it will not be renamed, if you rename the original note. The one references in the normal text, will be renamed by Obsidian. In my head, that is a pretty strong reason to keep as many references to the note names within the normal text, and not within the frontmatter.

Okay, I have made most of your suggestions – Thanks!

I agree that the updating-name-in-body-of-note is a good reason to keep that information in the note and not YAML header.

I am not sure why I create separate timeline files, either. Just seems a good thing to do, when I sometimes add details to that timeline-event, like photos, or I would want to add metatags to that event without adding more to the Source note.

Next for me is to write a simple parser so I can download Gmails as text files and import them into my vault. :slight_smile: I don’t want to pay a monthly fee for an “integration” app.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.