Possible to read file titles of a bookmark and dynamically populate prompt buttons?

I’m relatively new to creating custom actions and had a question:

I’m thinking of putting together an action that would read a folder in my Obsidian directory and populate a Prompt with a button for every file in that Obsidian directory.

My goal is to extend my existing action that allows me to pick which note in my /Lists directory I want to append the Draft to. The problem with my existing action is that every time I add a new file to that directory, I have to update my action to include it as an option.

Would reading through file titles and dynamically creating a prompt that lets me pick a file be possible? I’m having a bit of trouble figuring out if the Bookmark object would work for this.

Yes, you can create a FileManager for your bookmark with a script:

// create file manager using a Bookmark
let bookmark = Bookmark.findOrCreate("My-Folder");
let fm = FileManager.createForBookmark(bookmark);

I did something similar with Dropbox, here’s the script I used, which I hope you can use as a basis and modify.

() => {
	let path = "/Obsidian/RosemaryOrchard/Lists/";
	let content = draft.content;
	let replacementWords = ['watch', 'read'];
	replacementWords.forEach(function (word) {
		content = content.replace(new RegExp(word, "gmi"), "");
	});
	draft.content = content.trim();
	draft.update();

	// create Dropbox object and vars
	let db = Dropbox.create();
	let endpoint = "https://api.dropboxapi.com/2/files/list_folder";
	let args = {
		"path": path,
		"recursive": false,
		"include_media_info": false,
		"include_deleted": false,
		"include_has_explicit_shared_members": false,
		"include_mounted_folders": true
	};

	// make API request
	let response = db.rpcRequest({
		"url": endpoint,
		"method": "POST",
		"data": args
	});
	if (response.statusCode != 200) {
		console.log("Dropbox Error: " + response.statusCode + ", " + response.error + ' ' + db.lastError);
		context.fail();
	} else {
		let p = Prompt.create();
		p.title = "Pick a file";
		let fileList = response.responseData.entries;
		Object.keys(fileList).forEach(function(key) {
			if (fileList[key].name.endsWith('.md')) {
				p.addButton(fileList[key].name.replace(".md", ""), fileList[key].name);
			}
		});
		let didSelect = p.show();
		if (didSelect) {
			draft.setTemplateTag("append_path", path)
			draft.setTemplateTag("append_file",p.buttonPressed);
		} else {
			context.cancel();
		}
	}
}();
1 Like

Thanks for the tips! This was actually quite easy with the bookmarks feature once I knew to look for the FileManager.

let bookmark = Bookmark.findOrCreate("Lists");
let fm = FileManager.createForBookmark(bookmark);
let contents = fm.listContents("/");

let p = Prompt.create();
p.title = "Choose a list";

contents.forEach(listFile => {
	p.addButton(listFile.replace(".md","").replace("/",""));
})

var didSelect = p.show();

if (didSelect) {
	draft.setTemplateTag("file",p.buttonPressed);
} else {
	context.cancel();
}
1 Like