Run JavaScript code in your templates

Write simple JavaScript code into your templates to automate your note-taking, such as "Moving tasks from yesterday into today's note and marking them as scheduled" (see examples below).

You can execute JavaScript code in your templates and the results will be printed into your note. You also have access to NotePlans full JavaScript API

For example:

- <%- DataStore.projectNotes.length %>

Will print the total amount of your regular notes you have at the moment:

Writing code inside template tags

Every tag ( <%- code.returning.something() %>) can execute one line of code and return something. 

If you want to set a variable that you want to use in subsequent tags/code or execute code without printing anything, use the special tags ( <% code.setting.or.executing() -%>), for example:

<% const yesterday = new Date(new Date().setDate(new Date().getDate()-1)) -%>

Note: The dash "-" is placed at the closing tag, not at the opening one. This will not print anything into your note and just set the variable.

Now we can use the variable in the next tag, for example, to retrieve yesterday's note:

<%- DataStore.calendarNoteByDate(yesterday).filename %>

Or execute some code, such as opening yesterday's note in a split view:

<% const yesterday = new Date(new Date().setDate(new Date().getDate()-1)) -%>
<% Editor.openNoteByDate(yesterday, false, 0, 0, true) -%>

Examples

The following examples should get you a headstart so you can copy and paste and modify the code as you need it.

Copy yesterday's tasks

The following code will lookup the daily note from yesterday and take all open tasks and print them into your note if you are using it inside a template:

---
title: Copy yesterday's tasks
type: empty-note 
---
<% const yesterday = new Date(new Date().setDate(new Date().getDate()-1)) -%>
<%- 
DataStore.calendarNoteByDate(yesterday)
	.paragraphs
		.filter((p) => p.type == "open")
		.map((p) => p.rawContent)
		.join("\n") 
%>

Move yesterday's tasks to today and mark them as scheduled

The following code is slightly more complicated than the first because it also marks the open tasks which we moved to today as scheduled in yesterday's note, so they don't stay open. Additionally, you could open yesterday's note in a split view for reviewing it along with today's note. See a code example above.

---
title: Move yesterday's tasks
type: empty-note 
---
<% const yesterday = new Date(new Date().setDate(new Date().getDate()-1)) -%>
<% const note = DataStore.calendarNoteByDate(yesterday) -%>
<% 
	// Get the open tasks and empty lines in between
	const openTasks = note.paragraphs
		.filter(p => ["open", "empty"].includes(p.type)) 
-%>
**Moved from [[yesterday]]**
<%- 
	// Convert the paragraphs into plain text separated by linebreaks
	openTasks.map((p) => p.rawContent).join("\n") 
%>
<% 
	// Mark the open tasks as scheduled
	openTasks.filter(p => p.type == "open")
		.forEach((p, i) => { p.type = "scheduled" }); 
-%>
<% 
	// Update yesterday's note with the changes made above
	note.updateParagraphs(openTasks) 
-%>

Here is how it works in the end (the template is opened side-by-side with the daily note, so you can see how it works):