While working with Templater I realized I was accumulating a lot of templates. Some of the templates have properties in common and tried to find an efficient way to save creating more template files.
I came up with the idea of having a unique common template which could be modified on the fly from a selector. With some JavaScript and templater I would be able to delete, change and insert new properties in the common template, which has the name “My Stuff Template Test”. The selector templater is called “My Stuff Template Selector”.
The template selector will offer choices of different objects such as “My Code”, “My Computers”, “My Devices”, etc. When selecting any of these choices the common template will be modified according to the mapping in a dictionary. Finally, the resulting template will have the properties I need for that particular Obsidian page.
This is the content of “My Stuff Template Test.md”:
---
aliases:
type:
author:
up:
related:
summary:
status:
location:
rating:
tags:
purpose:
assigned:
purchased:
brand:
cost:
url:
folder:
partition:
language:
OS:
archetype: "[[My Stuff]]"
uuid: '<% tp.file.creation_date("YYYYMMDDHHmmss") %>'
---
And the following code belongs to the more elaborated “My Stuff Template Selector”:
<%*
const choices = ["Minimal", "My Code", "My Computers", "My Devices", "My Repositories", "My Virtual Machines"]
const choice = await tp.system.suggester(choices, choices);
let output = ""
let template = "[[My Stuff Template Test]]"
let fm_actions;
let yaml_str;
switch(choice) {
case "My Code":
fm_actions = {
"location": {Value: null, Action: "Delete"},
"author": {Value: null, Action: "Delete"},
"purchased": {Value: null, Action: "Delete"},
"brand": {Value: null, Action: "Delete"},
"cost": {Value: null, Action: "Delete"},
"assigned": {Value: null, Action: "Delete"},
"purpose": {Value: null, Action: "Delete"},
"tags": {Value: "content/code", Action: "Replace"},
"up": {Value: "[[Programming]]", Action: "Replace"},
};
yaml_str = await tp.file.include(template);
break;
case "My Computers":
fm_actions = {
"url": {Value: null, Action: "Delete"},
"folder": {Value: null, Action: "Delete"},
"language": {Value: null, Action: "Delete"},
"author": {Value: null, Action: "Delete"},
"purpose": {Value: null, Action: "Delete"},
"tags": {Value: "personal/assets", Action: "Replace"},
"up": {Value: "[[Equipment]]", Action: "Replace"},
"location": {Value: "[[Home]]", Action: "Replace"},
};
yaml_str = await tp.file.include(template)
break;
case "My Devices":
fm_actions = {
"url": {Value: null, Action: "Delete"},
"folder": {Value: null, Action: "Delete"},
"language": {Value: null, Action: "Delete"},
"OS": {Value: null, Action: "Delete"},
"author": {Value: null, Action: "Delete"},
"assigned": {Value: null, Action: "Delete"},
"tags": {Value: "personal/assets", Action: "Replace"},
"up": {Value: "[[Equipment]]", Action: "Replace"},
"location": {Value: "[[Home]]", Action: "Replace"},
};
yaml_str = await tp.file.include(template)
break;
case "My Repositories":
fm_actions = {
"OS": {Value: null, Action: "Delete"},
"purchased": {Value: null, Action: "Delete"},
"brand": {Value: null, Action: "Delete"},
"cost": {Value: null, Action: "Delete"},
"assigned": {Value: null, Action: "Delete"},
"location": {Value: null, Action: "Delete"},
"tags": {Value: "content/code", Action: "Replace"},
"up": {Value: "[[Programming]]", Action: "Replace"},
"status": {Value: "unknown", Action: "Replace"},
};
yaml_str = await tp.file.include(template);
break;
case "My Virtual Machines":
fm_actions = {
"location": {Value: null, Action: "Delete"},
"author": {Value: null, Action: "Delete"},
"purchased": {Value: null, Action: "Delete"},
"brand": {Value: null, Action: "Delete"},
"cost": {Value: null, Action: "Delete"},
"assigned": {Value: null, Action: "Delete"},
"language": {Value: null, Action: "Delete"},
"url": {Value: null, Action: "Delete"},
"tags": {Value: "task/virtualization", Action: "Replace"},
"up": {Value: "[[Virtual Machines]]", Action: "Replace"},
"status": {Value: "active", Action: "Replace"},
};
yaml_str = await tp.file.include(template);
break;
default:
output = await tp.file.include("[[Default Minimal Template]]")
fm_up = "[[None]]"
break;
// new Notice("No Matching Template")
}
for (var i=0; i<Object.entries(fm_actions).length; i++) {
dEntry = Object.entries(fm_actions)[i]
yaml_str = processYaml(i, yaml_str, dEntry);
};
tR += yaml_str
function processYaml(i, yml, d) {
let key = d[0];
let kv = d[1];
let value = kv.Value;
let action = kv.Action;
console.log("process(", i.toString(), ")\n", key, action, value)
switch(action) {
case "Delete":
yml = removeKey(yml, key);
return yml
break;
case "Replace":
yml = replaceKey(yml, key, value);
return yml
break;
case "Insert":
yml = insertKey(yml, key, value, "end");
return yml
break;
default:
new Notice("default pass")
// console.log(yml)
return yml;
break;
}
}
function removeKey(yml, key) {
yml = yml.split('\n')
.filter(function(line) {
return line.indexOf( key ) == -1;
}).join('\n')
// console.log("removeKey\n", yml)
console.log("= removeKey; ", "key:", key, "\n", yml)
return yml
}
function replaceKey(yml, key, value) {
const regex = new RegExp(key + ":\\s.*", "g")
const key_colon = key + ":"
const space = " ";
const apost = '"'
yml = yml.replace(regex,
key_colon
+ space
+ apost
+ value
+ apost);
console.log("= replaceKey; ", "key:", key, "; value:", value, "\n", yml)
return yml;
}
_%>
Am I reinventing something here?
I know about the plugin “Metadata Menu” but I have not been able to make it work with templater. Almost nil documentation on the subject.
I have also tried using processFrontmatter
but only works on the current template, not in the template that is being created, which I want to modify its properties.
Is there already a better way of doing this template customization without generating lots of templates?