pjeby/tag-wrangler

[Question] Example of integration with QuickAdd?

Opened this issue · 13 comments

I have tried the following code to automatically create a tag page by QuickAdd on alt-clicking a tag but failed. Could you please tell me how to achieve my goal?
image
image

pjeby commented

The this.registerEvent in the example was for plugin code; In the case of QuickAdd, it'd be app.plugins.plugins.quickadd.registerEvent.

Note, by the way, that your current code will result in two tag pages being created (assuming the create_tag_page choice creates one). For this particular use case, you should probably use tag-page:did-create instead, and modify the created evt.file. (E.g. by using a capture or template choice to add text at the end of it.)

pjeby commented

I've updated the documentation to better reflect how the will-create event works as well as how to integrate w/QuickAdd. And I've changed the event operation slightly to make it possible to integrate async file creation into the will-create event, but you'll need to update the plugin to 0.5.10 if you want to try that. (You'll also need to make the event handler not async or await anything, but rather set evt.tfile to the result of calling an async function.) See the docs for more detail.

After modifying the code according to your documentation, there are still some errors. Am I doing something wrong?

module.exports=
function auto_create_tag_page() {
	const TARGET_FOLDER = "all_notes/tag_pages/";
	app.plugins.plugins.quickadd.registerEvent(
		app.workspace.on("tag-page:did-create", (evt) => {
			const targetPath = TARGET_FOLDER + evt.file.basename + "." + evt.file.extension;
			console.log("filepath: " + targetPath);
			app.vault.rename(evt.file, targetPath);
			app.plugins.plugins.quickadd.api.executeChoice("create_tag_page", {
				filepath: targetPath
			});
			return;
		})
	)
}

image

pjeby commented

It looks like maybe the first error is that your tag_pages folder doesn't exist.

The second error is a result of the failed rename, but also you need to await the rename before executing the choice, or the choice may run before the rename is finished (causing the same error).

(Note: You can make the event handler async for did-create , it's only will-create that must be synchronous.)

Thank you for the reminder. I realize that I named the folder 'tagpages' instead of 'tag_pages', and have now corrected it. The final settings are as follows, and I hope it can serve as a reference for others with similar needs. And I am grateful for your help @pjeby, you are my hero!

  • Define a Capture choice:
    image
    image

  • Define a Macro choice:

    • image
    • Run this Macro on plugin load. image
  • Write some code in the script file:

module.exports=
function autoCreateTagPage() {
	const TARGET_FOLDER = "all_notes/tag_pages/";
	app.plugins.plugins.quickadd.registerEvent(
		app.workspace.on("tag-page:did-create", (evt) => {
			const targetPath = TARGET_FOLDER + evt.file.basename + "." + evt.file.extension;
			// need to wait for some time until tag-wrangler opens the new tag page, or there will be errors in console
			setTimeout(async () => {
				await app.vault.rename(evt.file, targetPath);
				app.plugins.plugins.quickadd.api.executeChoice("create_tag_page", {
					filepath: targetPath
				});
			}, 1000);
			return;
		})
	)
}
  • Done
pjeby commented

I'm curious why the timeout is necessary. I've now changed Tag Wrangler to open the file before firing did-create, so if you can check if that allows it to work without a timeout, that'd be good.

Update: The errors disappear after I update this plugin to v0.5.11 so setTimeout is not necessary now 🍾

There will be two errors without setTimeout or even the delay is below certain value like 200 in version 0.5.10

  • image image
  • imageimage

But other plugins may print errors in the console without setTimeout
image
I guess it's because some plugins listen to the file creation event and there is little interval between creating a new tag page by tag-wrangler and renaming it.

A better workaround might be sending an event called "alt-clicking a tag which doesn't have corresponding tag page" and doing nothing at all by tag-wrangler. It will also be more flexible for users.

pjeby commented

With the changes that I made today, it's now viable for a will-create listener to put a file promise in the event and that promise can wait for other things to happen before returning control to tag wrangler to open the file and send out the did-create event. I could probably add something to let event handlers tell Tag Wrangler to skip opening the file, though. e.g. evt.skipOpen = true or something of the sort.

OK, I'm looking forward to your future updates, and please let me know if you have finished those changes.

There is another problem. I don't know how to add frontmatter by QuickAdd without MetaEdit plugin. Could you add a flag like evt.skipCreate = true to tag-page:will-create event so that users are able to create a tag page, add aliases frontmatter and open the page totally on their own?

pjeby commented

Actually, if you set evt.file = Promise.reject("skip tag creation") in will-create, it should stop Tag Wrangler from creating the page at all. (There will be an error message in the console, but it won't mean anything bad.)

Cool, it works!