Templater: How do I add content after a file has ran JavaScript code editing its frontmatter?

How do I add content to a file after it has ran JavaScript code? My JavaScript code prompts the user for a title and for some tags using a multi-suggester. The code then uses the inputted tags to build the frontmatter dynamically.

<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");

	const file = tp.file.find_tfile(title);
	await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
		frontmatter['base'] = "[[Companies to talk to.base]]";
			
		frontmatter['tags'] = frontmatter["tags"] || [];
		frontmatter['tags'].push(...selectedTags);
	});
%>

Things I have tried

  • Plainly adding the content before and right after the JavaScript code
### Description

<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");

	const file = tp.file.find_tfile(title);
	await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
		frontmatter['base'] = "[[Companies to talk to.base]]";
		
		frontmatter['tags'] = frontmatter["tags"] || [];
		frontmatter['tags'].push(...selectedTags);
	});
%>

### More headers here
  • Displaying it
<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");

	const file = tp.file.find_tfile(title);
	await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
		frontmatter['base'] = "[[Companies to talk to.base]]";
		
		frontmatter['tags'] = frontmatter["tags"] || [];
		frontmatter['tags'].push(...selectedTags);
	});

	const desc = "### Description";
%>

<% desc %>
  • Using app.vault.modify
<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");

	const file = tp.file.find_tfile(title);
	await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
		frontmatter['base'] = "[[Companies to talk to.base]]";
		
		frontmatter['tags'] = frontmatter["tags"] || [];
		frontmatter['tags'].push(...selectedTags);
	});

	const desc = "### Description";

	await app.vault.modify(file, tp.file.content + desc);
%>

In all of the things I’ve tried that are listed above, I’ve tried both having the code as is, and inside the callback function of the on_all_templates_executed hook and still no luck. If it matters, I have my Templater settings set up in a way that if I create a new file inside the specified folder, it automatically applies the template. I don’t create a new file and manually select the “Templater: Open insert template modal” option from the Command Palette. Any advice?

Additionally, when should I use the on_all_templates_executed hook? I understand that whatever is inside the callback function runs after all of the templates have finished executing. I do have another, separate template that has the same code in adding the tags to the frontmatter dynamically THAT’S NOT inside the callback function of the hook, yet it still works. Why is that?

This one worked for me, it was your first suggestion but using tp.hooks as well.

### Description

<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");

	const file = tp.file.find_tfile(title);
	await tp.hooks.on_all_templates_executed(async () => {
	  await tp.app.fileManager.processFrontMatter(file, (frontmatter) => {
		  frontmatter['base'] = "[[Companies to talk to.base]]";
		  frontmatter['tags'] = frontmatter["tags"] || [];
		  frontmatter['tags'].push(...selectedTags);
	  });
	});
%>

### More headers here

The problem was that you were trying to update the note twice at the same time, once with your template content and once with tp.app.fileManager.processFrontMatter. tp.app.fileManager.processFrontMatter finished first, then your template content overwrote your entire note contents (including frontmatter/properties), so you were left with just note contents.

tp.hooks is the mechanism to get around that. You’re saying “don’t run this until Templater has settled so it’s save to run other file modifications on this same file without conflicts”.

Though on file creation, you know what’s even easier? Just writing out the frontmatter in the file. Here’s an example:

<%*
	const title = await tp.system.prompt("Enter company title: ");
	await tp.file.rename(title);

	const selectedTags = await tp.system.multi_suggester(['july-14', 'july-15', 'july-16'], ['july-14', 'july-15', 'july-16'], false, "Select the days the company will be there:");
-%>
<% "---" %>
base: "[[Companies to talk to.base]]"
tags: [<% selectedTags %>]
<% "---" %>

### Description

### More headers here