Using templeter to create a new file, and then immediately open it in an external application

I am trying to create a non-markdown file using templeter. I would like to create a file with the extension “.qmd” and then immediately open it (since obsidian can’t open this sort of file, it should be opened automatically in the default programme for the extension, in this case, RStudio).

Things I have tried

I have tried the following templater template:

<%*
let fn = await tp.system.prompt(“Filename”) + “.qmd”;
await tp.file.create_new(template = “QMD template”, filename = fn);
await app.workspace.getLeaf(app.vault.getAbstractFileByPath(fn))
%>

This correctly creates the .qmd file but doesn’t then open it. Using the ‘open_new’ option of tp.file.create_new doesn’t seem to work correctly either. I think that either getLeaf() is trying to open fn before create_new() has created it or that it isn’t the correct function for trying to open a non-md file. My knowledge of javascript is too rudimentary to figure it out.

What I’m trying to do

I am trying to create a qmd document from a templater template and then have this qmd document open in Rstudio. Once I have it open in Rstudio I will render the qmd to markdown and create a new .md page from it in the obsidian vault. This new page will automatically open in preview mode (thanks to the “Force note view mode” plugin) and have a dynamic templater template (<%+ … %>) in it which will again trigger the opening of the original qmd document.

Why do I want this? I want to embed the md page in other pages via ![[…]] but I don’t want to be able to edit it obsidian, instead, I want to edit the corresponding qmd file and then render that back to markdown in Rstudio, so as to be able to take advantage of all the benefits of qmd (executing r/python/julia code).

1 Like

The problem is that Obsidian/Templater are not necessarily geared to opening content in other applications. This is really operating system functionality.

With that in mind, the code below should open the newly created file by executing an ‘open’ command from a command line interface. It assumes you’re doing this on a MacOS computer. Note: this exact code is untested. Using some personal and web resources, I simply typed it up inside this forum’s window on a computer that does not have Obsidian or RStudio installed. Syntax errors are a distinct possibility.

//Your existing code
let fn = await tp.system.prompt("Filename") + ".qmd";
await tp.file.create_new(template = "QMD template", filename = fn);

//get the Obsidian file representation
let tf = tp.file.find_tfile(fn);
//get the absolute path of the file
let path = app.vault.getResourcePath(tf);
//escape any spaces in the path
path = path.replace(/(\s+)/g, '\\$1');
//build the CLI command
let cmd = `open -a RStudio ${path}`;
//execute the command
const { promisify } = require('util');
const exec = promisify(require('child_process').exec);
const out = await exec(cmd);

If you’re on Windows, I’m not certain what the equivalent command would be. Assuming .qmd files default to opening in RStudio, it could be as simple as NOT escaping the spaces in the path and using:

let cmd = `"${path}"`;

Hope this helps get you going in the right direction.

Thanks @ninjineer !

That got me most of the way there. What I got to finally work is the following:

<%*
let fn = await tp.system.prompt(“Filename”) + “.qmd”;
let path = await tp.file.path();
path = path.replace(/(Untitled.md)/g, fn);

let cmd = await ‘copy "’ + this.app.vault.adapter.basePath + ‘\Obsidian\qmd.md" "’ + path + ‘"’;
const { promisify } = require(‘util’);
const exec = promisify(require(‘child_process’).exec);
await exec(cmd);
const out = await exec(‘"’ + path + ‘"’);
%>

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