Create new file via Templater & open it in a new tab

I’m trying to create a new file, and then immediately open it in a new tab & focus it via Templater’s create_new method.

Using Dataview & Templater I’ve got it creating a file in the location I desire, and even have it so it opens said file after creation… But I just can’t get it to open the file in a new tab.

async function createNewNote(currentDirectory, targetTag, newFileMetadata) {
  const newNoteName = await prompt(`please enter a name for the note`);

  if ([null, ``].includes(newNoteName)) return;

  const currentFolder = app.vault.getAbstractFileByPath(currentDirectory),
    parentFolder = currentFolder?.parent,
    dataFolder = parentFolder?.children?.find(
      (child) => child?.name === `data`
    ),
    additionalMetadata =
      removeSpaces(newFileMetadata)?.replaceAll(`,`, `:\n`) + `:\n`,
    content = `---\n` + `tags: ${targetTag}\n` + additionalMetadata + `---\n`;

  // 'create_new' renamed via object deconstruction in the global scope
  createNew(content, newNoteName, true, dataFolder); 
}

That third parameter in the create_new method is seemingly the only option for opening the file with Templater after creation, at least with said method. I’ve searched the forums, reddit, the internet in general for a solution but can’t find anything.

Happy to use any alternative methods to get this to open in a new tab after creation.

I don’t think you can control in which tab it opens after template has started running (unless you do some serious javascript magic). But there are options you could try when you create the new file.

So my question is: How do you create the new file? Are you clicking on a link to a new file? If you just click it, it’ll be in the same window, but if you Cmd (or Ctrl) click it, it’ll open in a new tab.

It’s via a button. After I press the button I get the prompt for the name (via Templater; line 2 in original post). And then that createNew() function is what actually opens the file (currently in the same tab).

Full context:

const { update } = await this.app.plugins.plugins["metaedit"].api,
  { createButton } = await app.plugins.plugins["buttons"],
  templaterModuleArray =
    app.plugins.plugins["templater-obsidian"].templater.functions_generator
      .internal_functions.modules_array,
  templaterFileMap = templaterModuleArray[1].static_functions,
  templaterSystemMap = templaterModuleArray[4].static_functions,
  { create_new: createNew } = Object.fromEntries(templaterFileMap),
  { suggester, prompt } = Object.fromEntries(templaterSystemMap);

async function createNewNote(currentDirectory, targetTag, newFileMetadata) {
  const newNoteName = await prompt(`please enter a name for the note`);

  if ([null, ``].includes(newNoteName)) return;

  const currentFolder = app.vault.getAbstractFileByPath(currentDirectory),
    parentFolder = currentFolder?.parent,
    dataFolder = parentFolder?.children?.find(
      (child) => child?.name === `data`
    ),
    additionalMetadata =
      removeSpaces(newFileMetadata)?.replaceAll(`,`, `: \n`) + `: \n`,
    content = `---\n` + `tags: ${targetTag}\n` + additionalMetadata + `---\n`;

  createNew(content, newNoteName, true, dataFolder);
}

function createNewNoteButton(
  conatiner,
  currentDirectory,
  targetTag,
  newFileMetadata
) {
  createButton({
    app,
    el: conatiner,
    args: {
      name: "create new note",
      // color: "purple",
    },
    clickOverride: {
      click: createNewNote,
      params: [currentDirectory, targetTag, newFileMetadata],
    },
  });
}

const currentPage = dv.current(),
  { file, targetTag, newFileMetadata, sort, filterDetails, filters } =
    currentPage,
  conatiner = this?.container,
  { path: currentFilePath, folder: currentDirectory } = file;

createNewNoteButton(conatiner, currentDirectory, targetTag, newFileMetadata);

You could use the Obsidian workspace API:

E.g. following opens the file in a new split. You can also opt to have the file open in an existing panel, a new tab, window etc.

    const tFile = await app.vault.getAbstractFileByPath(filePath)
    await params.app.workspace.getLeaf("split", "vertical").openFile(tFile)

For a new tab you could:

  await params.app.workspace.getLeaf("tab").openFile(tFile)

I’ve got a QuickAdd script that prompts me for a natural language date and opens a the corresponding daily/weekly etc. log.

(Yep, I know that the awesome Periodic Notes does the same thing, but I wrote this a long time ago before I knew about Periodic Notes. I keep the code around because it is easily adaptable to other contexts and gives me full control over where the file opens (e.g., a new split).

async function OpenDailyLog(params) {
    const quickAddApi = params.quickAddApi
    const app = params.app
    var variables = params.variables
    const dts = await getUserDate(params, "Reference Date")
    if (!dts) {
        return
    }
    const referenceDate = moment(dts)
    const fileTitle = referenceDate.format("YYYY-MM-DD") + ".daily.log"
    const referenceYear = referenceDate.format("YYYY")
    const referenceMonth = referenceDate.format("MM")
    const referenceDay = referenceDate.format("DD")
    const referenceDayName = referenceDate.format("dddd")
    const referenceWeek = referenceDate.format("WW")
    const folderRoot = "logs"
    const filePath = folderRoot + "/" + referenceYear + "/daily/" + fileTitle + ".md"
    const newFileContent = ""
    await requireFile(
        params,
        filePath,
        newFileContent,
        true
    )
    const tFile = await app.vault.getAbstractFileByPath(filePath)
    await params.app.workspace.getLeaf("split", "vertical").openFile(tFile)
    // https://marcus.se.net/obsidian-plugin-docs/reference/typescript/classes/Workspace
    // await params.app.workspace.getLeaf().openFile(tFile)
    return filePath
}

2 Likes