Automatically update Project ID Value in Frontmatter

I am trying to do the following for my project notes. If I am creating a new project note via a template, I would like to have a “Project ID” that counts up so I can use that ID as a filter in dataview.

The frontmatter I currently use (and update manually) is:

---
projectid: P001
---

Example:
“Project 1” has “projectid” “P001”; I create a new note “Project 2”; I am adding my project template to that note; the fontmatter updates the “projectid” to “P002”.

Is this somehow possible? I heard the “templater” plugin is able to do that, but I can’t figure out how, because I am too unfamiliar with it.

Thank you

First you need a convenient place to stash your current project value. I chose to use a simple text file, which I stored in the same folder as my other Templater scripts. The only content in this file is the current value.

File: project-counter.txt

1

Then I set up a Templater template as follows.

File: project.md

<%*
//get a handle on the counter file
const counter = tp.file.find_tfile('project-counter.txt');
//read the current counter value
let count = parseInt(await app.vault.read(counter));
//increment the count
count++;
//save the updated counter value
await app.vault.modify(counter,`${count}`);
-%>
---
projectid: P<% count.toString().padStart(3,'0') %>
---
<% tp.file.cursor() %>

Note, this template assumes you’re applying this template to a blank note. If you need something more advanced that creates the note and stores it in a particular location, there are examples of doing that sort of thing floating around.

1 Like

Wouldn’t it be just as easy to do a Dataview query, and select the highest project id, and then increment that? Is it needed to actually store the project id in a file of its own?

On a related note, how many projects are you like to create during a month/year? Would it be a viable alternative to just use some combination of the year and day-of-year to generate project ids, i.e. 22349 (for day 349 of '22)? They would not be sequential, but then again you would know when you started (or thought of) that particular project. For me such project ids would be a little easier to remember than pure sequential numbers (but this is a matter of personal preferences, for sure)

And if you feel up for it, I would strongly consider setting up templater to trigger the new project note for new files within your project folder. So that when you create a new file in there, (or hit a particular hot key,) it setups the new project for you, properly with ID’s, tags, and what-not.

I use this sort of ID system, and it’s a lot easier to implement if you add some redundancy to the metadata and skip the leading zeros, especially if you’re not much of a coder:

---
id: P1
idnum: 1
tags: project
---

That makes querying it much simpler, and assists in sorting and counting.

You could then use a Templater template like this to generate that header with the next ID:

<%*
const dv = DataviewAPI;

var minimumID = "0";
var categoryTag = "project";
var categorySlug = "P";

var allNums = await dv.pages("#" + categoryTag).idnum.sort();
var nextID = await allNums[allNums.length - 1] + 1;
if (Number.isNaN(nextID)) { nextID = minimumID; }
var slugID = categorySlug + nextID;

tR += "---\n";
tR += "id: " + slugID + "\n";
tR += "idnum: " + nextID + "\n";
tR += "tags: " + categoryTag + "\n";
tR += "---\n"; 
%>

Note that you also need Dataview installed to use the above template.

2 Likes

Hi everyone —
Thank you very much for your suggestions.
I need to be honest, I found a way easier way to solve my initial problem. The “Project ID” was just a workaround because I didn’t know that there was a way to use the …

where contains(Project, [[]])

… query to have the file name automatically updated in dataview if I would ever change it. (That’s why I wanted to use a “Product ID” that stays consistent)

This also means (for future readers of this thread) that I can’t confirm if the proposed solution works or not.

Still, thank you very much for taking the time and proposing a solution.