Frontmatter updates

Looking for some assistance
I work with clients from different companies. I keep meeting notes and people notes.
On my meeting notes, I have meeting participants and I enter here the participants (which exist on people notes).
When I create a people note,
-the title of the note is the person’s name “John Smith”
-I fill out the company name. Example “Contoso”
-I set the alias to “John Smith (Contoso)” ({file name} ({Company})
So on my meeting notes (under participants) I would enter the alias as it is best for me to see the company name here as opposed to simply the name

Is there any way to automate the alias step?

In other words you want to automatically generate properties when creating a note. This can be done using Templater, Linter, Shell commands and QuickAdd (inline scripts). Obviously all of them are advanced community plugins so crafting the solution will take up time even by experienced users.

This example is from Obsidian dev docs:
https://docs.obsidian.md/Reference/TypeScript+API/FileManager/processFrontMatter

app.fileManager.processFrontMatter(file, (frontmatter) => {
    frontmatter['key1'] = value;
    delete frontmatter['key2'];
});

Thanks
So I am kind getting the hang of it
I was able to put together a rudimentary way to do this
My current flow,

  1. During a meeting I realized I need to add a participant, I start typing and if the person exists use that entry. Otherwise type name as text
  2. Right after the meeting, see participant list for participants that are not wikilinks but text. I manually add [[ and ]] to make it a wikilink
  3. I click the wikilink and create a blank note
  4. Use templater to create a people note (has a couple of templater scripts - created from current date and name from file name
  5. I manually enter the company name
  6. I manually compose alias with name - company name

For step 6

a. I can not use templater normally for alias since it would be executed when I create the note when company is not populated
b. Instead of step 6, I can copy / paste the templater script on the alias field and execute right there

Yes this is kind of solution and it requires pressing a keyboard shortcut or ⌘P and selecting Templater: Insert templates/my template 1.md.

templates/my template 1.md:

<% tp.file.title %> (<% tp.frontmatter["company"] %>)


1 Like

Thanks
I also see some inspiration here

So far I have only used templater when creating a new file but it seems you can use templater to execute a script on an existing note and modify carefully certain fields

I looked that thread. Function app.vault.modify was used to modify the whole file. This is very clunky solution and you should use app.fileManager.processFrontMatter instead. In your case you need to programmatically ask values when creating your file because otherwise you need to create your file manually and then apply the shortcut. You can ask values using Modal form community plugin. In this case the code look like this

---
<%*
const modalForm = app.plugins.plugins.modalforms.api;
const result = await modalForm.openForm('example-form');
tR += result.asFrontmatterString();
-%>
---

In above asFrontmatterString() is provided by the plugin. The template/code is used to generate full frontmatter and I think you should use app.fileManager.processFrontMatter to modify existing frontmatter.

2 Likes

ok, thanks. This led me in a good direction. I have been reading about templater, openform, metaedit
I really don’t want to open a form or click a button.
I was able to mock up what I wanted to do with dataviewjs and metaedit
Below is a concept just to see how things connect/work. It works automatically every time page refreshand will copy “created” field over “aliases”

const {update, getPropertyValue} = this.app.plugins.plugins["metaedit"].api;
const newvalue = dv.current().file.frontmatter.created;

//const current = await getPropertyValue (pn, file);
await update('aliases', newvalue, dv.current().file.path);

The problem is that metaedit does not “respect” lists. By the way, I don’t care about any previous entry. I am not trying to append. Happy to have a list with one entry

Ok this works to make the updates.
Note that I am including this on my people notes which have frontmatter and the body is only dataviewjs. So the file structure / length /content is well understood.


function replaceAlias(y, x) { // Define the regex to match the alias pattern 
const regex = /(aliases:\n\s{2}-\s)(.+?) \((.+?)\)/; // Replace the matched part with the new alias using x 
return y.replace(regex, `$1${x}`); }

// Get the current file path 
const filePath = dv.current().file.path; 
const file = app.vault.getAbstractFileByPath(filePath);
let contents = await app.vault.read(file);
let newname = dv.current().file.frontmatter["full-name"] + " (" + dv.current().file.frontmatter.company + ")"

const newContent = replaceAlias(contents, newname);
//dv.paragraph(newname);
app.vault.modify(file, newContent)

And credit to @AlanG who provided inspiration

Hi. Did you have particular reason not to use app.fileManager.processFrontMatter? I think this would make the code simpler.

@blue_emperor
no reason other that I don’t know what I am doing. :flushed_face:
I am not a technical person / programmer but don’t mind exploring / playing around. And generative ai is very helpful as well navigating this
I will look into function that to see if it makes things simpler / more robust.

@SanDiegoBoy yes, you’ll want to use processFrontMatter now. The code above from 2022 was before that function existed.

This is how I do things now from Templater:

<%*
setTimeout(() => {
  app.fileManager.processFrontMatter(tp.config.target_file, frontmatter => {

    // Update or add as many fields as you want
    frontmatter['Some property'] = 'Some value'
    frontmatter['Another property'] = 'Some other value'

    // You can even remove properties if you want
    delete frontmatter['Unwanted property']

  })
}, 200) // the reason for the timeout is to let the template complete first
-%>
2 Likes

@AlanG Apologies for my ignorance first
I was able to mock something up borrowing some code. It works but I notice again the “problem” of style for multiline properties. Is there a way around it ?

ORIGINAL
aliases:

  • John Paul 4

WANTED
aliases:

  • Mr beat

GOT
aliases: Mr beat

// get the current file and check if the "Date Completed" property is blank (but also present). If so then set it to the current time with MomentJS
let file = app.workspace.getActiveFile();
await app.fileManager.processFrontMatter(file, (fm) => {
    
        fm["aliases"]  = "Mr beat";
    });

Answering my own question. It works well if you properly configure things :grimacing: with [“Mr beat”]

let file = app.workspace.getActiveFile();
await app.fileManager.processFrontMatter(file, (fm) => {
    
        fm["aliases"]  = ["Mr beat"];
    });

And the final script for anybody interested

const fname = dv.current().file.frontmatter["full-name"];
const comp = dv.current().file.frontmatter.company;
let newname;
if (comp != null) {
newname = fname + " (" + comp + ")";
} else {
newname = fname;
}


let file = app.workspace.getActiveFile();
await app.fileManager.processFrontMatter(file, (fm) => {
    
        fm["aliases"]  = [newname];
    });

I’m not a programmer but I was thinking what code you can run inside app.fileManager.processFrontMatter(file, (fm) => {...here...}

Could you access fname using const fname = fm["full-name"] and comp using const comp = fm["company"] inside (fm) => {...}? This would make using Dataview unnecessary.

I don’t know how to run javascript code other than dataviewjs / templater
Do you ?

I read about Javascript little bit. You can access frontmatter values inside (fm) => {...} using fm["my-property"], reassign property values using fm["my-property"] = new value and delete properties using delete fm["my-property"]. The content inside (fm) => {...} can be any code or empty. There might be cleaner functions to just read properties but this processFrontMatter can read, write and delete. Again if you want to just read then use such function that allows only reading. I think this is usual paradigm in programming.

Yes I got you now. Read and write should be possible using processfrontmatter and without using dv.current.file…