Select Template inside of a Template

Hello all,

I have multiple templates that are working perfect for me.
Now I would like to choose a template inside of a template so I don’t have to reuse the same code 100 times through each and every template of mine.
Here is what I have.

Template #1

<%* 
const colors = [
	'orange',
	'yellow', 'yyellow',
	'gray',
	'blue','bblue','cyan',
	'green', 'ggreen', 'sqlgreen', 'comment',
	'red', 'rred', 'sqlred',
	'purple', 'ppurple'
	'pink', 'ppink', 'sqlpink',
	'vsaction', 'vshelper', 'vspink',
	'gold', 'silver', 'litesilver',
	'brown']; 

let color = await tp.system.suggester(colors,colors,false,'Color'); 

if (color !== null) { 
	tR = `<span class="fs8 ${color}">${ tp.file.cursor()}</span>`; 
} 
-%>

I want to have a separate template for my colors, so I can go to each template and use that instead of having an array of colors in every template of mine and if I add a color then I have to go to every single one.

Thank you.

Templater allows for user functions to be defined, and this is a perfect candidate for a user function. See User Scripts - Templater for the original documentation.

First you need to dedicate a folder for these user functions, and set which folder you chose in Settings > Templater (User Script Functions) > Script files folder location.

Within this folder you create one file for each user function, so say we aim to create chooseColor, you would create the file chooseColor.js (not it has to have the .js extension, and not .md (or .js.md). This means in most cases, that you need to edit this file outside of Obsidian.

The contents of this file needs to follow a given format for it to be recognised as a user function, but it’s not that hard, so if I copy-paste your code we end up with:

async function chooseColor() {

  const colors = [
 	'orange',
	'yellow', 'yyellow',
	'gray',
	'blue','bblue','cyan',
	'green', 'ggreen', 'sqlgreen', 'comment',
	'red', 'rred', 'sqlred',
	'purple', 'ppurple'
	'pink', 'ppink', 'sqlpink',
	'vsaction', 'vshelper', 'vspink',
	'gold', 'silver', 'litesilver',
	'brown']; 

  return await tp.system.suggester(colors, colors, false, 'Color');
}

module.exports = chooseColor;

Note that after you’ve defined it, and refreshed Obsidian’s/Templater’s look of user function, should include your newly defined function in a list under the script folder mentioned earlier.

Now your Template #1 could look like:

<%* 
const color = await tp.user.chooseColor();
if ( color !== null ) {
  tR += `<span class="fs8 ${color}">${ tp.file.cursor() }</span>`; 
} 
-%>

Caveat: If your user function has compiler errors, it’ll hinder all templates from being executed, so if you get some strange error messages in the Console (of Developer Tools), verify that you don’t have any issues in either of your user functions. (This is most likely a case, just when you’re developing your user functions.

1 Like

thank you very much! I am a developer so javascript shouldn’t be an issue for me.

I’ll give this a try when I have a bit of time and let you know how it went.

1 Like

Hello, I am so close to getting this working.
Sorry its been a long time since I asked this question.

I can see my User Script Functions in the Templater tab under settings.
So my .js script is appearing. I made sure its saved as .js
Detected 1 User Script(s)

When I go to call this script I get a console error:

Templater Error: Template parsing error, aborting. tp is not defined

I set it up just like your post.
Here is my template. and my function.

<%*
let color = await tp.user.chooseColor();

if (color !== null) { 
	tR = `<span class="fs16 ${color}"><b>${ tp.file.selection() }</b></span>`; 
} 
-%>

async function chooseColor() {
	const colors = 
	[
		'orange',
		'yellow', 'yyellow',
		'gray',
		'blue','bblue','cyan',
		'green', 'ggreen', 'sqlgreen', 'comment',
		'red', 'rred', 'sqlred',
		'purple', 'ppurple',
		'pink', 'ppink', 'sqlpink',
		'vsaction', 'vshelper', 'vspink',
		'gold', 'silver', 'litesilver',
		'brown'
	 ];

	return await tp.system.suggester(colors, colors, false, 'Color');
}

module.exports = chooseColor;

I’m not sure why, but I sometimes see references where you when calling the function include the tp in the call:

<%*
let color = await tp.user.chooseColor(tp)
...
%>

And then in the user function do:

async function chooseColor(tp) {
  ...
}

module.exports = chooseColor;

Does that change yield a better result for you?

1 Like

WOWW Thank you!~
That was my issue,
That also makes no sense LOL needing a parameter when I’m not passing anything in.
But thank you so much it worked!

1 Like

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