How to change the directory of Default location for new notes through plugin API?

Obsidian has a configuration option that is

  • Folder to create new notes in

    Newly created notes will appear under this folder. Plugin settings will override this

  • Default location for new notes

    Where newly created notes are placed. Plugin settings will override this

I was hoping to find a way to configure the Default location as . /${filename}_/, but the software does not support this.

I’ve looked at the Obsidian help API, but it doesnt seems to find a place to view or modify this value.

I need a little help: I’ve constructed the path through the current focus’s file, how do I replace the directory of Default location for new notes through plugin API?

// This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
    // Called when the user clicks the icon.
    const currentFile = this.app.workspace.getActiveFile() ?? undefined;
    if(currentFile){
        new Notice('Hello world!');
        console.log("currentFile",currentFile);
        const my_folder = currentFile.vault.adapter.basePath.replace(/\\/g, '/') +"/" + currentFile.basename+"_";
        
        if (fs.existsSync(my_folder)) {
            console.log('This already has my_folder!', my_folder);
        }else{
            fs.mkdirSync(my_folder);
            // fs.writeFileSync(my_folder+"/UnNamed.md");  // it doesn't work
            console.log('New folder is created.', my_folder);
        }
    }
});

Why I want to do that?

Because I need to change the logical order of the new notes. The notes represented by the two numbers next to each other naturally have the notion of “order” relationship, i.e., there is an A->B.
But when I think of a new, chunky, independent thing C from A, the sequence of notes I want becomes A → C → B. The relationship between them is like the distance of rational numbers, although the intimate distance is not the same, but C is closer than B. C fills the gap between A and B.

You can modify those settings via this.app.vault.setConfig('newFileLocation', ...) or this.app.vault.setConfig('newFileFolderPath', ...) (see here), but I don’t think the default file location can be specified in a dynamic templating format.

So I suggest making a new command that replaces the default “Create new note” command.

One more thing: fs is only available on desktop, so it is recommended to use the Vault interface instead, e.g. this.app.vault.create and this.app.vault.createFolder.

1 Like

thank you for helping. The method you mentioned works very well, but there is a problem, if replacing the create action with a new function, there will appear a lot of secondary problems, such as, ①how to display the file in the editor after creating it, ②how to generate file in a specific path after clicking on a wiki link, adn so on.

so I would like to ask if there is a mechanism similar to reflection, which can intercept the create action, and before note create, checks if a folder described by newFileFolderPath is stored, and if it doesn’t exist, then creates it?

I try to use registerEvent,but on('create') only called when a file is created.

this.registerEvent(this.app.vault.on('create', this.handleCreate.bind(this)));

P.S.1 obsidian-custom-attachment-location stacks up what I expected. but it can only modify the location of attachments. It provides a way to use template strings.

let NoteFolderPath: './assets/${filename}.md';

class TemplateString extends String {   // Support ${filename} 
    interpolate(params: Object) {
        const names = Object.keys(params);
        const vals = Object.values(params);
        return new Function(...names, `return \`${this}\`;`)(...vals);
    }
}

getNoteFolderPath(mdFileName: string) {
        let path = new TemplateString(this.settings.NoteFolderPath).interpolate({
            filename: mdFileName
        });
        return path;
    }

P2. Current progress

....
	updateNoteFolderConfig(path: string){
		console.log("update Note Folder Config.");
		this.app.vault.setConfig('newFileLocation', "folder");
		this.app.vault.setConfig('newFileFolderPath', path);
	}

    getNoteFolderPath(mdFileName: string) {
        let path = new TemplateString(this.settings.NoteFolderPath).interpolate({
            filename: mdFileName
        });
        return path;
    }
	getNoteFolderFullPath(mdFolderPath: string, mdFileName: string) {
        let attachmentFolder = '';

        if (this.useRelativePath)
            attachmentFolder = Path.join(mdFolderPath, this.getNoteFolderPath(mdFileName));
        else {
            attachmentFolder = this.getNoteFolderPath(mdFileName);
        }
        return normalizePath(attachmentFolder);
    }

	async handleFileOpen(file: TFile | null): Promise<void>{
		console.log('Handle File Open');
		if (file == null) {
            console.log("No file open");
            return;
        }

        if (file.extension !== 'md'){
            console.log('file.extension !== md');
            return;
		}
		let mdFileName = file.basename;
		// let path = this.getNoteFolderPath(mdFileName);
		// console.log(path);
		// this.updateNoteFolderConfig(path);

        let mdFolderPath: string = Path.dirname(file.path);
		let fullPath = this.getNoteFolderFullPath(mdFolderPath, mdFileName);
	
		this.updateNoteFolderConfig(fullPath);
		// this.app.vault.createFolder(fullPath);
	}


	async handleCreate(){
		console.log('Handle Create');
		// let path = this.app.vault.getConfig('newFileFolderPath');
		let currentOpenedFile = this.app.workspace.getActiveFile();
		if(currentOpenedFile == null){
			console.log(' no opened file.');
			return;
		}
		const filepath = await this.app.vault.getConfig('newFileFolderPath');
		console.log(filepath);
		this.app.vault.createFolder(filepath);

		let newFileName = filepath + "/UN.md"
		this.app.vault.create(newFileName,"")
		this.app.workspace.
	}