Are tiddler save hooks possible?

For tiddlers that match a set of rules (like having or not having a certain field, value of title/text field matching a certain regexp string provided via variable/config tiddler etc), is it possible to hook into the saving mechanism and display some messages or even modify tiddlers in batch mode just before saving them? Is it also possible to cancel the save if certain conditions are not met? If all of this is possible, which docs can I read to learn about it and is it possible to be done in wikitext or is it necessary to write JavaScript modules?

An analogy would be commit hooks in Git for example.

The save-tiddler-actions macros is responsible to save a tiddler in the EditTemplate.

The keyboard shortcut and the editor toolbar button both call the same macro. So if you would change that macro, you can change the behaviour in wikitext. The responsible message is tm-save-tiddler

I am not sure, what you want to achieve with “…even modify tiddlers in batch mode…”, since the edit template only can handle 1 tiddler. So “batch mode” does not make too much sense in that context.

If you want to change the behaviour for the navigator-widget, you will need a js-plugin, which uses the th-saving-tiddler hook, with the plugin hook-mechanism.

The hooks also only can handle tm-save-tiddler events. So eg: action-setfield widgets can not be “intercepted” using that hook.

1 Like

Perhaps it’s better to ilustrate the question with at least one less abstract use case I’m thinking about.

I have a wiki where my tiddlers have redundant information:

  1. tiddlers have tags (in the TiddlyWiki sense of tags). so a tiddler can have tags +foo , +bar. here the + prefix is a personal convention of mine.
  2. they also have tags specified in the text field. the tiddler above would have a tags: foo, bar line, usually right after the title. this is for historical reasons that go back to the pre-TiddlyWiki era of that data

Currently I sync those manually as I create, edit tiddlers, but I wonder if there’s an automated, preferably no-JS, TiddlyWiki-only way of doing that.

Ideally, it shall look like this:

  1. I create a hook tiddler containing wikitext, where currentTiddler is the tiddler that is going to be saved, and which I can modify. (Not for this particular example, but optionally it would be nice if I could conditionally abort the saving entirely)
  2. I tell TiddlyWiki this is my save hook. In Git, I do this by having scripts of special name in a specific directory of the repo. In TiddlyWiki, by analogy with toolbar buttons or styles, I’d expect to be able to do it by tagging tiddlers with a special system tag, like $:/tags/saveHook
  3. The script itself will get the tags of currentTiddler, then find the tags: ... line in the text field, parse it, sync both sets of tags (honoring the + prefix in TiddlyWiki tags), and ultimately save the tiddler.

Are you trying to preserve both the TW tags and the redundant tags: line in the text field, and keep them perpetually in sync with each other?

  • If not, it’d be easiest to write a one-time-use button that will make all the necessary edits at the same time (without entering edit mode at all). Happy to help workshop this if you want to go this route.
  • If so… I’d still seriously consider whether you can eliminate the redundancy. A ViewTemplate would be one easy way to display data from the tags field in a different format.
3 Likes

Are you trying to preserve both the TW tags and the redundant tags: line in the text field, and keep them perpetually in sync with each other?

Yes.

I’d still seriously consider whether you can eliminate the redundancy. A ViewTemplate would be one easy way to display data from the tags field in a different format.

I can’t eliminate redundancy (yet?), because I’m still using the knowledge base outside of TiddlyWiki, so I have scripts that expect tags: foo, bar lines in my files.

As for templates, there’s no need for additional lobbying, after your help with that template that displays multiline streams nodes as expandable, it became my top indispensable daily usage plugin. I’m surelly willing templating to become a first class citizen in my TiddlyWiki workflows but this will still take a while to grok it (as well as transclusion, which seems to be a tightly coupled concept to templating).

Regarding save hooks, I can see many other uses.

Like having linting rules for tiddler content, that would cancel the tiddler saving if an unwanted pattern is detected.

Or like automatically creating and saving more tiddlers when a certain tiddler is saved.

Is this currently possible?

Do you use a single-file wiki or Node.js based configuration?

1 Like

I don’t believe it is, though it’s certainly been discussed before (e.g. A Modular Action Mechanism For Tiddler Save Button). You might want to make a formal request via GitHub issue so it doesn’t slip through the cracks again.

In the meantime: the save button ($:/core/ui/Buttons/save) uses the macro <<save-tiddler-actions>>, which is defined in $:/core/ui/EditTemplate as follows:

\define save-tiddler-actions()
\whitespace trim
<$action-sendmessage $message="tm-add-tag" $param={{{ [<newTagNameTiddler>get[text]] }}}/>
<$action-sendmessage $message="tm-add-field" $name={{{ [<newFieldNameTiddler>get[text]] }}} $value={{{ [<newFieldNameTiddler>get[text]] :map[subfilter<get-field-value-tiddler-filter>get[text]] }}}/>
<<delete-edittemplate-state-tiddlers>>
<$action-sendmessage $message="tm-save-tiddler"/>
\end

You could edit this macro to add additional action widgets.

Alternately, as a less invasive option, you could clone $:/core/ui/Buttons/save, add your extra action widgets to the cloned version, and remove the $:/tags/EditToolbar tag from the original. This would effectively replace the default save button with a visually identical button that includes your additional functionality.

3 Likes

Both. Do you have in mind anything that works with only one of these setups?

it’s certainly been discussed before (e.g. A Modular Action Mechanism For Tiddler Save Button )

Thanks for mentioning this :+1: . The solution proposed there looks very similar to what I have described above. I think making fuss with core feature requests is still premature, at least before I get to try that all buttons actions demo, maybe it’ll just suit me.