Creating stacking Templater actions (or how to create multi-line Templater action outputs?)

Hey all! Trying to create a template where multiple Templater actions build on top of each other. I’m not a skilled hand at JavaScript, so it’s possible this is an easy solution.

Here’s the code I’m trying to get to work, and I’ll explain it below:

tags: workorder
site: "[[<%* dv = app.plugins.plugins.dataview.api; let array = await dv.pagePaths('"Sites"'); tR += await tp.system.suggester(array, array, true, "Which site?"); %>]]"
address: "<%* dv = app.plugins.plugins.dataview.api; tR += await; %>"

I’m creating a “Work Order” note and attempting to attach two metadata values: “site” and “address”.

The “site” metadata is fetched using DataviewJS inside of a Templater action - tp.system.suggester is fed an array of potential sites based on the DataviewJS request, which returns the path of the proper “site” note, which is then linked because of the enclosing double brackets.

The “address” metadata is fetched by referencing the new value associated with “site” on this note, and uses DataviewJS in the Templater action to get the address on that linked note. So for instance, if site: "[[Sites/Liberty]]", it would find the “address” metadata on the Liberty Bell note and return Philadelphia.

Both of these lines of code work independent of the other, so if I just have the first one, it’ll return Sites/Liberty no problem. If I have site set to the “Liberty Bell” value already, the address metadata returns “Philadelphia” no problem.

But if I run them both simultaneously, it errors out because it thinks there’s no note listed at the note’s “site” metadata, even though it runs me through the selection process.

Is there a way to make these run in a strict order, such that one fully resolves before the next one begins? Or, if there’s a good way to create just a block of javascript that internally references the site value for the address and then fills everything all at once, that’s great, too. I just don’t know where to start to do multiline outputs for Templater. :sweat_smile:

It looks like you have a race condition, i.e., Templater needs “some time” to process the tR += directive and Dataview is too fast in trying to determine the value of .site.

I am just brainstorming. What about:

  • separating the address: line into its own file and to tp.file.include it? This might already be enough of a delay to work.
  • using setTimeout to delay the execution of the function?


Ah, race condition! Thank you! I’ve heard the term before, but it’s nice to hear it applied to my situation— I feel like I understand what that means, now.

I’ve tried tp.file.include with the address line in a different file, but I ran into the same race condition. I didn’t want to try setTimeout because I felt like there had to be a better way.

I ultimately have landed on this solution, after discovering that \n results in a new line. I’m just going to bring the entire metadata block into a single Templater execution command:

/* Set up values for DataView use within this block and an easy to read value for starting a new line */
const dv = app.plugins.plugins.dataview.api;
const newLine = "\n";

/* tags field */
tR += "tags: workorder" + newLine;

/* site field, linking this work order to the applicable site note */
let siteArray = await dv.pagePaths('"Sites"');
const woSite = await tp.system.suggester(siteArray, siteArray, true, "Which site?");
tR += "site: \"[[" + woSite + "]]\"" + newLine;

/* address field, pulled from the linked site note */
let address = await;
tR += "address: \"" + address + "\"";

That code now results in this, when run:

tags: workorder
site: "[[Sites/Liberty]]"
address: "Philadelphia"

I’ll leave this open for a bit in case anyone else has a more elegant solution, but this at least solves the problem of the race condition.

1 Like

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