How can I pull data with two dots into another note in a template Templater

Good day, dear experts!
Please tell me what code should be written in the Templater template so that the following conditions work for me?

What I have:
Note 1
Note 1 has a field
URL:: - inserted into this field from the Internet
(I don’t use frontmatter for URL - because I need a clickable link)
Note 2
I create a new note 2 according to the template
Question?
what should be written in the template so that the URL from note 1 appears in note 2 when the template is inserted? How can this be implemented?

Here’s something to get you started. There’s plenty you can do to embellish or improve this template, including prompting for a file name.

<%*
const field = 'URL:: ';
let url = '';

//Break content of current note into two parts: everything before the `field`
//text and everything after it.
const parts = tp.file.content.split(field);

//I expect that parts.length == 2. If it equals 1, then there was no `field`
//in the content. If is greater than 2, then there are multiple instances of
//the `field` in the content and I'll assume we want to work with just the
//first one.
if (parts.length >= 2)
{
   //The URL value is everything from the start of the second element of 
   //`parts` up to the first end of line. This assumes the `field` was not 
   //on the last line of the note.
   url = parts[1].split('\n')[0];
}

//Assemble the content of the new note including the URL
const content = `
URL:: ${url}

# Title
Whatever other content you want
`;

//Make the new note
await tp.file.create_new(content);
-%>

Since this probably won’t be the only time you need to get the value for such a field, I would recommend making a user function. (Note: this implementation uses a regular expression to get to the value, but the same assumptions apply.)

function fieldValue(content,field)
{
   let result = {field:field, value:''};
   const regex = new RegExp(field + ':: (.*)\n');
   let m = content.match(regex);
   if (m !== null)
   {
      result.value = m[1];
   }
   return result;
}
module.exports = fieldValue;

Then from your Templater template you’d call it like:

const url = tp.user.fieldValue(tp.file.content,'URL');
// use url.value to get at the actual url in this case
1 Like

Thank you for your detailed answer!
Unfortunately, I’m just learning how to code.
If it doesn’t bother you and you have free time, could you write what code you need to insert into the template to get:
There are [[Note 1]]
Note 1 has a URL line:: Obsidian

i create a new note link inside Note 1
let’s call it [[Note 2]]
what code should be written in the template so that when creating a note based on the template, URL:: Obsidian appears in [[Note 2]]

If you don’t mind, you can write the code based on this example
Again, I’m sorry, I’m new.

If I’m following, you’re saying you have a note file like the following in edit mode:

Note 1.md

URL:: [Obsidian](https://obsidian.md)

# Note 1

bla bla bla [[Note 2]] bla bla.

At this point Note 2 does not exist. You want to be able to click on the link for Note 2 and end up with a new note with the following content:

Note 2.md

URL:: [Obsidian](https://obsidian.md)

# Note 2

Problem is, it cannot happen. Obsidian is smart enough to recognize when a wikilink does not exist and create the missing file. Also, with the right configuration, it can apply a template to the new note after it creates that file. Unfortunately, this template is operating in the context of a blank document at that moment. There’s no linkage that the template can access to tell it Note 1 was previously involved, so it can’t get at that desired URL value.

As a workaround of sorts, while you’re in Note 1, you could make a selection of the text Note 2 (i.e. all the characters within the [[]]) instead of clicking on the link. The selected text will become the file name of the new note when you then run the following template:

<%*
let url = '';
let name = tp.file.selection;
if (!tp.file.find_tfile(name))
{
   const regex = new RegExp('URL:: (.*)\n');
   const m = tp.file.content.match(regex);
   if (m !== null) { url = m[1]; }
   const content = `URL:: ${url}

   # ${name}

   `;
   await tp.file.create_new(content,name);
}
-%>

Note, the above script does make any attempt to assure the selected text (or lack thereof) will make a valid file name. It does, however, silently avoid attempting to create the same file twice.

Hope this helps.

2 Likes

Thank you so much for these detailed answers!
It really put me on the right track.
I thank you for your responsive help!

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