How to use nested suggester to execute multiple templates

I am trying to group my templates by purpose using dictionaries inside templater.
My aim is at reducing the number of template files and maintain them from a master template. At most, I think I will have 3 or 4 master groups: (i) for creation of classes or archetypes; (ii) intellectual production; (iii) devices inventory; (iv) papers collection.

I have the dictionary part of the classes for the properties practically done, thanks to @holroy and @gino_m. What I need now is to connected the templates that contain the dictionaries to a suggester which would allow to select the respective master template.

The problem I am facing is how to execute/run a template from the suggester selector. By execution I mean, running the template as we do with Alt+N and then pick the template.

This is how the master selector, or “selector of templates”, looks:

selector of templates

<%*
const items = ["item 1", "item 2", "item 3"];
let subitems;
let selectedItem = await tp.system.suggester(item => item, items);

if (!selectedItem) {
	// No selected option, user hit `Escape` key
	return
}

switch (selectedItem) {
	case "item 1":
		subitems = ["template-11", "template-12", "template-13"];
		break;
	case "item 2":
		subitems = ["template-21", "template-22", "template-23"];
		break;
	case "item 3":
		subitems = ["template-31", "template-32", "template-33"];
		break
	default:
		console.log("nothing")
}
console.log(subitems);

selectedItem = await tp.system.suggester(item => item, subitems);

console.log(selectedItem)
const file = tp.file.find_tfile(selectedItem);
// await app.vault.load(file);
// await app.vault.process(file);
// await app.vault.read(file);
-%>

And these are a couple of templates that I want to execute from suggester:

template-11

<%*
const classes = [
  { name: "My Articles",
	prefix: "art",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/article",
		archetype: "[[My Stuff]]"
		}
    
  },	
  { name: "My Posts",
	prefix: "post",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/post",
		archetype: "[[My Stuff]]"
		}
  },	
  { name: "My Repositories",
	prefix: "repo",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/repo",
		archetype: "[[My Stuff]]"
		}
  },	
]

console.log(classes);
tR += "We are at " + tp.file.title
tR += "\nClass Groups\n"
tR += "-------------------\n"
classes.forEach(item => {
	tR += item.name;
	tR += "\n"; 
});
%>

and:

template-21

<%*
const classes = [
  { name: "Devices",
	prefix: "dev",
	folder: "Inventory",
    fields: {
	    summary: "",
		tags: "inventory/devices",
		archetype: "[[Inventory]]"
		}
    
  },
  	
  { name: "Computers",
	prefix: "comp",
	folder: "Inventory",
    fields: {
	    summary: "",
		tags: "inventory/computers",
		archetype: "[[Inventory]]"
		}
  },
  
  { name: "Audio",
	prefix: "aud",
	folder: "Inventory",
    fields: {
	    summary: "",
		tags: "inventory/audio",
		archetype: "[[Inventory]]"
		}
  },
]
console.log(classes);
tR += "We are at " + tp.file.title
tR += "\nClass Groups\n"
tR += "-------------------\n"
classes.forEach(item => {
	tR += item.name;
	tR += "\n"; 
});
-%>

All this works but it just read the templates, they are not executed.

Any ideas?

How about changing the logic and go for what you did before:
await tp.file.include("[[Default Minimal Template]]");?

Yes, I tried it. It doesn’t do anything.
I added this code based on your sugesstion await tp.file.include("[[template-11]]"), but doesn’t work:

if (selectedItem == "template-11" ) {
	new Notice(selectedItem);
	await tp.file.include("[[template-11]]");
} else if (selectedItem == "template-21" ) {
	new Notice(selectedItem);
	await tp.file.include("[[template-21]]");	
}

Modified selector of templates

<%*
const items = ["item 1", "item 2", "item 3"];
let subitems;
let selectedItem = await tp.system.suggester(item => item, items);

if (!selectedItem) {
	// No selected option, user hit `Escape` key
	return
}

switch (selectedItem) {
	case "item 1":
		subitems = ["template-11", "template-12", "template-13"];
		break;
	case "item 2":
		subitems = ["template-21", "template-22", "template-23"];
		break;
	case "item 3":
		subitems = ["template-31", "template-32", "template-33"];
		break
	default:
		console.log("nothing")
}
console.log(subitems);

selectedItem = await tp.system.suggester(item => item, subitems);

if (selectedItem == "template-11" ) {
	new Notice(selectedItem);
	await tp.file.include("[[template-11]]");
} else if (selectedItem == "template-21" ) {
	new Notice(selectedItem);
	await tp.file.include("[[template-21]]");	
}

tR += selectedItem
console.log(selectedItem)
-%>

I am sure I am missing something, but I don’t know what.

I am expecting that after selecting the template, it will execute the template tied to the selected option by suggester, but it doesn’t.

The interest thing though is that all dictionaries get printed to the console, while nothing with tR += gets “printed” in the new note.

In the following script, I added console.log(item.name, item.prefix);, and works: it prints all the values in the dictionary.

<%*
const classes = [
  { name: "My Articles",
	prefix: "art",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/article",
		archetype: "[[My Stuff]]"
		}
    
  },	
  { name: "My Posts",
	prefix: "post",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/post",
		archetype: "[[My Stuff]]"
		}
  },	
  { name: "My Repositories",
	prefix: "repo",
	folder: "My Stuff",
    fields: {
	    summary: "",
		tags: "content/repo",
		archetype: "[[My Stuff]]"
		}
  },	
]

console.log(classes);

tR += "We are at " + tp.file.title
tR += "\nClass Groups\n"
tR += "-------------------\n"
classes.forEach(item => {
	console.log(item.name, item.prefix);
	tR += item.name;
	tR += "\n"; 
});
_%>

Why doesn’t tR += work?

In one of my scripts, this works:

    if (builtinReplacementChoice === "Remove InlineQueries") {
        // Include the separate Templater template file
        await tp.file.include("[[Remove InLineQueries Template]]");
  • Doesn’t work without await.

I got it to work!
It was a silly thing. The result of reading the template has to be loaded into a variable, then tR it. Like so:

txt = await tp.file.include("[[template-11]]");
tR += txt;

So, the final working master multi template selector is:

<%*
const items = ["item 1", "item 2", "item 3"];
let subitems;
let selectedItem = await tp.system.suggester(item => item, items);

if (!selectedItem) {
	// No selected option, user hit `Escape` key
	return
}

switch (selectedItem) {
	case "item 1":
		subitems = ["template-11", "template-12", "template-13"];
		break;
	case "item 2":
		subitems = ["template-21", "template-22", "template-23"];
		break;
	case "item 3":
		subitems = ["template-31", "template-32", "template-33"];
		break
	default:
		console.log("nothing")
}
console.log(subitems);

selectedItem = await tp.system.suggester(item => item, subitems);

let txt;
if (selectedItem == "template-11" ) {
	new Notice(selectedItem);
	txt = await tp.file.include("[[template-11]]");  //read template
} else if (selectedItem == "template-21" ) {
	new Notice(selectedItem);
	txt = await tp.file.include("[[template-21]]");	
}

tR += txt;     // execute the template

tR += selectedItem
console.log(selectedItem)
-%>

1 Like

Is this for a more user-friendly (Wang-solution like) fourth iteration of the MTP?

Yes. I gave a hint at doing it in my answer to @holroy on the “Meta Template Picker”. He was expecting the MTP to work with a suggester selector, but that part was not ready yet. The MTP is an underlying part. Now, I have to tie both solutions.

A Meta Template Picker iteration to manage multiple templates based on dictionaries - Share & showcase - Obsidian Forum

One thing that comes obvious after using/working this template script so many times is that are clearly three parts identified: the properties declaration for many classes in a dictionary; the process of acting on the instructions in that dictionary; and the utility functions. I was thinking what if I were able to insert any dictionary, instead of being stuck at one, at the top, at will?

1 Like

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