Find and replace only within YAML frontmatter (regex?)

Things I have tried

Lots of web searching and experimenting with BBEdit

What I’m trying to do

I’m seeking a way to make batch changes within the YAML header. Mostly adding and removing tags. But I wouldn’t want to affect anything outside the header.

I’m thinking this is beyond the power of regex. You need to select the text between the two “—” and then do a find/replace within that selection. It seems like some app would have to drive this–and be able to do it for all files in a folder.

I thought there might be a community plug-in for managing YAML, but found nothing. Is this a weird idea? Seems like a lot of Obsidian users would want some kind of YAML manager.

Or is there a much easier way to do this that I just haven’t figured out. I’m an artist, not a developer. :wink:

Thanks!

4 Likes

You can use the metaedit plugin.
I made a script where it updates the frontmatter and “completes” a habit by adding a “:heavy_check_mark:” emoji. The script takes a completed “true” and “false” argument: it removes this “:heavy_check_mark:” emoji from the frontmatter. I create 2 templater notes so I can tie those to a button from the buttons plugin.

Perhaps my code can help you out for your project:

Frontmatter in my daily note:

---
habits:
  - uhive::
---

Templater notes

Change Metadata Uhive

<% tp.user.change_metadata(tp,app,"uhive",true) %>

Remove Metadata Uhive

<% tp.user.change_metadata(tp,app,"uhive",false) %>

Templater script file

change_metadata.js

async function my_function (tp,app,habit,completed) {
    const filetitle = tp.file.title
    const file = tp.file.find_tfile(filetitle) 
    const {update} = app.plugins.plugins["metaedit"].api
    if(completed == true) {
        completed = "✔️"
    } else if (completed == false) {
        completed = " "
    }
    await update("  - "+habit,completed,file)
    console.log("Finished")
}
module.exports = my_function

Optional: button configuration from buttons plugin

Change metadata:

```button
name Uhive
type command
action Templater: Insert Obsidian Vault/Templates/Templater/Metadata/Change Metadata Uhive.md
color blue
class button
\```
^button-uhive

Remove metadata:

```button
name Pinterest
type command
action Templater: Insert Obsidian Vault/Templates/Templater/Metadata/Remove Metadata Uhive.md
color blue
class button
\```
^button-rmuhive

Swap button which swaps between both buttons up here

```button
name Uhive
swap [uhive,rmuhive]
color blue
class button
\```
^button-swapuhive

Now you can use button-swapuhive in your daily notes and the button will update + remove the “:heavy_check_mark:” emoji when clicked.

Optional: Display the metadata beneath the inline button we just created in a table

This is a code block for the dataview plugin

```dataview
table without id
date.day as "Day",
habits[0]["uhive:"] as "Uhive"
from #daily and -"Template"
where date = date(2022-03-14)
sort date
\```

Sorry if I went overboard with this, my script goes even deeper than that, but I guess this might already be overwhelming.

3 Likes

Thanks for the generous and comprehensive reply. I’ll check it out…

Regards,
Russell

1 Like

It kinda works for my test vault. The problem is that it keeps adding undefined in the yaml after each trigger. So for example this is my yaml after several check and uncheck:

---
habits:
  - uhive:: ✔️
undefinedundefined
undefinedundefinedundefined
---

Do you know why is that? I don’t use the button as well as the dv script

That is probably because your “return” is not in your script or is trying to output a variable that is undefined.

To fix this you can add this to the end of your script (js) file:

return ""
1 Like

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