Give all existing Notes an (additional) frontmatter property from file

What I’m trying to do

I want to force correct metadata in all notes of my vault, be they existing or new.

Give all existing Notes in the vault a frontmatter property with type date and the value of the files ctime.

If no frontmatter exists for a note it should be created.

I imagine a kind of batch process .

Things I have tried

Looked around in the forums and the templater documentation. All solutions I found work during note creation. My problem are the existing notes.

I would implement this with a template that I triggered once, within which I’d list all the vault files, and loop over them updating metadata with the ctime.

I would also make sure to back everything up before I attempted this!!

It’s easy to get at ctime without needing it explicitly written down in the yaml, but I assume you’re doing this for interoperability with some other software?

here’s a piece of templater I use a lot to do timestamps that shows off javascript and api calls to tweak yaml:

<%* 
const newTime = tp.date.now("YYYY-MM-DD[T]HH:mm:ss") 
await app.fileManager.processFrontMatter(tp.config.target_file,
  fm => { fm.check = newTime })
_%>

A couple useful calls:

The Linter plugin is super useful. It will update YAML attributes and it can get timestamp dates from the file. Maybe it would do what you want?

Thank you ! I found some snipptes here https://zachyoung.dev/posts/templater-snippets/

and produced this:

<%*
await Promise.all(
  app.vault.getMarkdownFiles().map(async file => {
    try {
      await app.fileManager.processFrontMatter(file, (frontmatter) => {
        frontmatter.created_at = file.stat.ctime;
      });
    } catch (err) {
      console.error(`Failed to process ${file.path}\n\n${err}`);
    }
  })

);
-%>

But created_at is a number :frowning:

Yes indeed. Linter with a miminal configuration (for the dates) . Lint all Notes and done.

The javascript route makes sense for more complicated problems

1 Like

oh yeah it’s probably representing time as an integer, so you’d want to convert it with some kind of date formatting method.

something like this would work:

moment(1454521239279).format("DD MMM YYYY hh:mm a") //parse integer

I never spent any time with linter so it’s nice to hear it can do things like this. In any case, now you have the foundation to tinker if you need to do something like this again.