QuickAdd - using active file frontmatter

What I’m trying to do

I want to get some of the frontmatter properties from the currently active file and pass them as quickadd variables to a quickadd template (in a QuickAdd macro). For example, I have an author note and I want to create a new book note. The author name would come from the current active author note and get passed to the book note as a QuickAdd variable and inserted into the book note.

Things I have tried

I figured out how to do this with a QuickAdd user script (aka, some javascript which becomes a step in the QuickAdd macro). However, it feels like I’m using a sledge hammer to pound in a pin. Is there an easier way to do this?

I don’t think QuickAdd has any builtin references to frontmatter, but I’m not very familiar with QuickAdd. I’ve just made a few macros in different contexts, and I’m happy to use javascript either as separate files or as user scripts. This could possibly be considered a sledge hammer, but then again if it does the job…

However, I’m questioning why not just use Templater if your main purpose is to create a new file based upon current file? It has potential to pickup up information from the current file, to be used when creating a new file.

I don’t believe what you suggest works (I tried it). The problem is that the new note is created before templater does it’s thing. Therefore references to frontmatter or other properties end up refering to the new note not the (old) active note)

If you stand in a book note, and insert a template into it, it’ll pick up the current frontmatter. The trick then is that this template doesn’t actually insert anything into the current file, but creates the new file instead and opens that in a new tab.

You are correct, that it’ll not work if you just trigger new note from that file, but I’m explicitly talking about inserting a file into the current file which doesn’t actually insert anything (or it could insert a link if you wanted it to) but instead it creates the new file.

I’m not sure I understand. Are you thinking I should be using tp.config.active_file in my capture quickadd? I haven’t done that, but I could try that. I would suspect tp.file.create_new() would have the same problem I mentioned above.

For starters you could try out this template:

<%* 
const author = tp.frontmatter.author
const newBookTitle = await tp.system.prompt("New book title")
const content = `---
author: ${ author }
---
`

await tp.file.create_new(content, newBookTitle, false)

tR += `Created new book: [[${ newBookTitle }]]\n`
_%>

This will ask for the title of the new book, and create that note in the background with a predefined author. In this template I set the open_new parameter to false, which allows us to also insert a link from the original file (where the author was originally defined).

But if you read the tp.file.create_new docs, you can also set it to true and open the file, and as a (side?) effect the template will then be applied to that file.

With it set to true we could then also have made the template above like the following:

<%* 
const author = tp.frontmatter.author
const newBookTitle = await tp.system.prompt("New book title")
await tp.file.create_new('', newBookTitle, true)

// Now the new file is "active" for the rest of this template
_%>
---
author: <% author %>
---

My glorious book: <% newBookTitle %>

<% tp.file.cursor() %>

Some more text

Trigger either of these template from within an active file editor, and it’ll pick up the author, ask for the book title and create the new book note. You can if you want, also specify folders, and of course change the template to whatever you want it to be.

1 Like

Sorry to take so long to get back to you on this. I got your first solution to work. It took some modifications to my vault as there was things (that you wouldn’t be aware of) that I do in my vault that interferred with it. But I could make it work once I backed out one of my settings.

I couldn’t make the second solution work. The book note always ended up empty. Not sure if there was something I was missing or not.

I did find GitHub - jaltgen/obsidian-meeting-workflow: Demoing my newly created meeting-workflow.. His use case is meetings in projects, but he’s doing basically the same thing I wanted. I’m going to try that next.

And, thanks for all of your help and insights. I really do appreciate it. Cheers

1 Like

Your sledgehammer is the tool I needed! :pray:

If anybody is, like I was, interested for another usecase, here is a user script that does the thing.

This is useful to me for a capture choice that creates a new task in my daily note and tags it with the “tagName” of the project I was working on (that is the project’ name formatted as a tag in camelCase). The script grabs the active note’s frontmatter and passes predetermined fields as values to the next action.

Usage: create a macro with this user script as a first action, and then the capture choice, in my case something like - [ ] #task #{{value:tagName}} {{value:New task}} appended to the current daily note.

// Fetch the frontmatter from the active file
async function fetchFrontmatter() {
    const activeFile = app.workspace.getActiveFile();
    if (!activeFile) {
        new Notice("No active file.");
        return;
    }

    const fileContent = await app.vault.read(activeFile);
    const frontmatterRegex = /^---\n([\s\S]*?)\n---/;
    const match = frontmatterRegex.exec(fileContent);

    if (!match) {
        new Notice("No frontmatter found in the active file.");
        return;
    }

    const frontmatter = match[1];
    const frontmatterLines = frontmatter.split("\n");

    const frontmatterData = {};
    frontmatterLines.forEach(line => {
        const [key, value] = line.split(":").map(part => part.trim());
        frontmatterData[key] = value;
    });

    return frontmatterData;
}

// Main function to be called by QuickAdd
module.exports = async (params) => {
    const frontmatterData = await fetchFrontmatter();
    if (!frontmatterData) {
        return;
    }

    // Pass the frontmatter values as QuickAdd variables
    params.variables = {
        ...params.variables,
        author: frontmatterData.author || '',
        title: frontmatterData.title || ''
        // Add other frontmatter fields as needed
    };
};

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