What I’m trying to do
I am trying to create a meta-bind button using the js-engine that will be used to create a note.
As part of setting up the button a note template, and the place to create the note are required parameters.
Here is an example of a hard coded path meta-bind button creation framework:
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: ""
id: ""
style: default
actions:
- type: templaterCreateNote
templateFile: 04 - ACTIVE PROJECTS/_PROJECT TEMPLATE/07 MEETING LOGS/TMP - MEETING LOG.md
folderPath: 04 - ACTIVE PROJECTS/_PROJECT TEMPLATE/07 MEETING LOGS
openNote: true
Things I have tried
Here is a version of code I have been working with for the js-engine plugin to create the button. The issue is I am not having any success on getting the template and path data extracted from the template YAML:
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
// Retrieve TMP_PATH and LOG_PATH from the current file's frontmatter
const tmpPath = mb.getMetadata(mb.parseBindTarget(#TMP_PATH));
const logPath = mb.getMetadata(mb.parseBindTarget(#LOG_PATH));
// Debug Statements: Display the retrieved TMP_PATH and LOG_PATH values
engine.markdown.create(`DEBUG: Retrieved TMP_PATH: ${tmpPath}`);
engine.markdown.create(`DEBUG: Retrieved LOG_PATH: ${logPath}`);
// Check if TMP_PATH and LOG_PATH exist
if (!tmpPath || !logPath) {
return `Error: TMP_PATH or LOG_PATH is not defined in the current file's YAML frontmatter.`;
}
// Dynamically generate the Meta-Bind button
const button = `
\`\`\`meta-bind-button
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: ""
id: ""
style: default
actions:
- type: templaterCreateNote
templateFile: ${tmpPath} # Retrieved dynamically from TMP_PATH
folderPath: ${logPath} # Retrieved dynamically from LOG_PATH
openNote: true
\`\`\`
`;
return engine.markdown.create(button);
Here is another failed attempt at trying to set up dynamic paths for the meta-bind button by accessing a DATA_PRJLOGS YAML parameter in a note titled “PROJ_INFO” in the current directory.
And access the “TMP_PATH” YAML in the current note.
The meta-bind button requires a template parameter and a path parameter to create a new note.
Here is the non-working attempt:
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
const comp = new obsidian.Component(component);
// Step 1: Retrieve the current folder dynamically
const currentFolder = mb.getMetadata(mb.parseBindTarget("file.folder", ""));
if (!currentFolder) {
return "Error: Unable to determine the current folder.";
}
// Step 2: Construct the path to the PROJ_INFO file in the same folder as the current note
const projInfoPath = `${currentFolder}/PROJ_INFO.mb`;
if (!mb.getMetadata(mb.parseBindTarget(`${projInfoPath}`, ""))) {
return `Error: PROJ_INFO file does not exist at path: ${projInfoPath}`;
}
// Step 3: Retrieve metadata properties from the respective sources
const dataProjLogs = mb.getMetadata(mb.parseBindTarget(`${projInfoPath}#DATA_PRJLOGS`, ""));
if (!dataProjLogs) {
return "Error: DATA_PRJLOGS is not defined in the PROJ_INFO note's YAML.";
}
const tmpPath = mb.getMetadata(mb.parseBindTarget("TMP_PATH", ""));
if (!tmpPath) {
return "Error: TMP_PATH is not defined in the current file's YAML.";
}
const logPath = mb.getMetadata(mb.parseBindTarget("LOG_PATH", ""));
if (!logPath) {
return "Error: LOG_PATH is not defined in the current file's YAML.";
}
// Step 4: Render the button dynamically
function render() {
// Ensure metadata is valid before rendering
if (!dataProjLogs || !tmpPath || !logPath) {
container.createEl("div", { text: "Error: Required metadata is missing." });
return;
}
// Create the Meta-Bind button
const button = `
\`\`\`meta-bind-button
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: "Click to create a new project log"
id: "create-project-log-btn"
style: default
actions:
- type: templaterCreateNote
templateFile: ${tmpPath} # Use TMP_PATH
folderPath: ${logPath} # Use LOG_PATH
openNote: true
\`\`\`
`;
// Render the button to the container
comp.unload(); // Reset component lifecycle
comp.load();
container.empty();
mb.wrapInMDRC(engine.markdown.create(button), container, comp);
}
// Step 5: Create a reactive component that listens for metadata changes
const reactive = engine.reactive(render, {
dataProjLogs: mb.getMetadata(mb.parseBindTarget(`${projInfoPath}#DATA_PRJLOGS`, "")),
tmpPath: mb.getMetadata(mb.parseBindTarget("TMP_PATH", "")),
logPath: mb.getMetadata(mb.parseBindTarget("LOG_PATH", "")),
});
// Step 6: Subscribe to metadata changes and refresh the component
mb.subscribeToMetadata(
mb.parseBindTarget(`${projInfoPath}#DATA_PRJLOGS`, ""),
component,
(value) => reactive.refresh({ dataProjLogs: value })
);
mb.subscribeToMetadata(
mb.parseBindTarget("TMP_PATH", ""),
component,
(value) => reactive.refresh({ tmpPath: value })
);
mb.subscribeToMetadata(
mb.parseBindTarget("LOG_PATH", ""),
component,
(value) => reactive.refresh({ logPath: value })
);
// Return the reactive component
return reactive;
another failed attempt:
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: ""
id: ""
style: default
actions:
- type: templaterCreateNote
templateFile:#TMP_PATH
folderPath:#LOG_PATH
openNote: true
Here is a working solution to pull yaml data from the current note to define the paths required in a create new file button:
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: ""
id: ""
style: default
actions:
- type: templaterCreateNote
templateFile: !path(#TMP_PATH) # Correct way to reference TMP_PATH
folderPath: !path(#LOG_PATH) # Correct way to reference LOG_PATH
openNote: true
here is a failed attempt of trying to pull a YAML path value from another note in the current note directory:
const mb = engine.getPlugin('obsidian-meta-bind-plugin').api;
const comp = new obsidian.Component(component);
// Step 1: Get the current folder dynamically
const currentFolder = mb.getMetadata(mb.parseBindTarget("file.folder", ""));
if (!currentFolder) {
return "Error: Unable to determine the current folder.";
}
// Step 2: Construct the `PROJ_INFO` file path dynamically
const projInfoPath = `${currentFolder}/PROJ_INFO`;
if (!mb.getMetadata(mb.parseBindTarget(`${projInfoPath}`, ""))) {
return `Error: PROJ_INFO file does not exist at path: ${projInfoPath}`;
}
// Step 3: Retrieve `TMP_PATH` from the current note
const tmpPath = mb.getMetadata(mb.parseBindTarget("TMP_PATH", ""));
if (!tmpPath) {
return "Error: TMP_PATH is not defined in the current note's YAML frontmatter.";
}
// Step 4: Retrieve `DATA_PRJLOGS` from the `PROJ_INFO` file
const dataProjLogs = mb.getMetadata(mb.parseBindTarget(`${projInfoPath}#DATA_PRJLOGS`, ""));
if (!dataProjLogs) {
return "Error: DATA_PRJLOGS is not defined in the PROJ_INFO file's YAML frontmatter.";
}
// Step 5: Render the Meta-Bind Button dynamically
const button = `
\`\`\`meta-bind-button
label: "CREATE A NEW PROJECT LOG"
icon: ""
hidden: false
class: ""
tooltip: "Click to create a new project log"
id: "create-project-log-btn"
style: default
actions:
- type: templaterCreateNote
templateFile: ${tmpPath} # Dynamically retrieved from TMP_PATH in the current note
folderPath: ${dataProjLogs} # Dynamically retrieved from DATA_PRJLOGS in PROJ_INFO
openNote: true
\`\`\`
`;
// Step 6: Render the button
comp.unload(); // Clear the component for lifecycle management
comp.load();
container.empty();
mb.wrapInMDRC(engine.markdown.create(button), container, comp);
return engine.markdown.create(button);