Idea: Addition to core hacking button actions


Please find attached a macro (or version of) I would like to have included in the next release.


  • This will allow the ability to add actions (Action Widgets) to existing buttons such that macros, plugins and solutions can make use of the existing button use, this is in a hackable way to avoid core tiddler changes (after this facility is added to the core buttons.
  • There are many actions a user/designers may want to do within tiddlywiki which requires a trigger, this typically forces the bespoke button to achieve this, and demands the user click another button. By leveraging the existing buttons new actions can be added at appropriate times including but not limited to examples such as;
    • On edit button
    • On close or Done
    • On save-wiki

button-actions-macro.json (515 Bytes)

\define button-actions(buttonname)
<$list filter="[tag[$:/tags/button-actions/$buttonname$]]" variable=button-action-tiddler>
   <$transclude tiddler=<<button-action-tiddler>>/>
;Button action tags in use
<$list filter="[tags[]prefix[$:/tags/button-actions/]]" variable=button-action-tag>
   <$macrocall $name=tag tag=<<button-action-tag>>/>

Note: after the \end is ignored when generating the macros, what follows helps users track the tags in use.

It can be installed on with no apparent changes beyond the macros existence.

This enables a macro as follows;
<<button-actions "buttonname">> where button name is an arbitrary button name, although a later step would be to update the majority of core buttons to use this (described later).

This macro however will transclude all tiddlers into the actions parameter tagged

Thus a button can be created as follows;

<$button actions=<<button-actions "MyButton">> >

and then clicking “MyButton” will trigger the actions in all tiddlers tagged $:/tags/button-actions/MyButton

Thus without returning to a buttons invocation and editing it in future additional actions can be added to every button that contains actions=<<button-actions "MyButton">> simply by placing additional actions in a tiddler and tagging it $:/tags/button-actions/MyButton, with the added feature that they may be actioned in the order of the tagged items.

As this solution is now;

  • This will encourage users to follow a de facto standard when developing buttons in their solutions, allowing other solutions or plugins to add actions where necessary or convivence and integration without the need to edit each others buttons.
  • We may suggest by example that such “action tiddlers” be named with the button-actions or similar in its name.
  • Most existing buttons respond only to click, using this method actions responding to the modifier keys “on click” can be added by user/designers without core changes.

What is next?

  • Update the majority of core buttons. With the above macro in place I propose changing most core buttons [all[shadows]prefix[$:/core/ui/Buttons/]] not already using the “actions=” parameter with actions=<<button-actions "buttonname">> where button name is the name following “$:/core/ui/Buttons/” eg; $:/core/ui/Buttons/save-wiki gets actions=<<button-actions "save-wiki">>
  • This includes buttons for the view and edit toolbars and the page controls (toolbar)
  • If the above macro or a version of it is accepted I would hopefully proceed with updating most core button widgets before the next release.

The exceptions to above can be found with [all[shadows]prefix[$:/core/ui/Buttons/]search[actions=]] and each of these handled separately, ideally to bring them inline with the same approach.

An outstanding question?

  • Please Consider; Lets say you wished to have an action occur when a user clicks any button. You would create a single action tiddler and tag it with all the various $:/tags/button-actions/*buttonname* or alternatively add the action to multiple tiddlers with the appropriate tags.
  • This could be used to log the button usage of your wiki for analytics or designer/user feedback.

The Question;

  • Would it be acceptable to include in the solution an additional “virtual tag” such as $:/tags/button-actions/all where tiddlers so tagged will contain actions to be executed for all buttons? This is mainly due to the possible performance impact, but would it be less if used with a single tag anyway if someone chose to go with it anyway?

Extending this concept later;

  • A similar treatment of these on Editor Toolbar buttons, would be useful but requires additional research.
  • Providing a matching solution for other actions not on existing core buttons, and in other widgets such as the selectwidget ETC… in this case we may add tags of the form $:/tags/actions/actionname
  • A method to do the same on open or navigate to a tiddler would also be highly desirable, for example; opening select tiddlers, could start a timer, but also requires additional research.

Here is an example of a modified core tiddler;

$__core_ui_Buttons_save-wiki.json (1004 Bytes)

Updating this with the above macro will still do nothing until something is tagged with $:/tags/button-actions/save-wiki

Now add the following tiddler to the same wiki;
new-save-wiki-action.json (238 Bytes)

Next time when you click on save wiki, if the address begins “file://” it will save the full path and filename to the clipboard allowing a simple ctrl-v (On windows) to past the full path and filename into the save dialogue and save (with overwrite prompt) - assumes you can choose where to download.

These tags do not exist unless used, although there will be one defined for each button. Perhaps we can call these “virtual tags”.

@TW_Tones this seems like a pretty interesting idea. If I’m understanding it, it results in the ability to add extra actions to the ‘events’ of core buttons via tag, which seems consistent with how the rest of TiddlyWiki’s hackability is setup.

  • Add pieces to standard layout with $:/tags/PageTemplate :heavy_check_mark:
  • Add content to each tiddler using $:/tags/ViewTemplate :heavy_check_mark:
  • Add content to standard sidebar using $:/tags/Sidebar :heavy_check_mark:
  • Add macros to core macros by using $:/tags/Macro :heavy_check_mark:
  • Add actions to standard buttons using $:/tags/button-actions/buttonname :grey_question:

( reference on layout hackability)

I might propose a naming convention closer to the others like just $:/tags/Action/... or something for consistency, but that’s kind of beside the point.


This will need to be rewritten with v5.2.1 because of this PR: Add “cascade” filter run prefix and use it to control view templates #6168 which is tested at the moment.

There is no documentation atm other then the changes made by the PR. We are still in the phase of identifying possibilities to use it …

It would be interesting to see, if it works with the TW buttons too. … I didn’t test it atm.

Yea, from the first view if it’s added to the core imo that would be the right tag: $:/tags/Action/...


@TW_Tones … with which buttons did you test the concept. … I think it’s page and tiddler toolbar buttons. right?

1 Like

Thank you @TW_Tones for the clear exposition. It’s a good idea, and I’m keen to have something like it.

The core does already use tag-based actions for startup actions:

The actions should be generic; we would invoke $:/tags/Actions/DeleteTiddler not just from the button but also via keyboard shortcuts or any other place where the UI deletes tiddlers.


Mario see the original post

Any button not already using the actions= on the button widget is a candidate.

[all[shadows]prefix[$:/core/ui/Buttons/]] not already using the “actions=” parameter with actions=<<button-actions "buttonname">>

  • This includes buttons for the view and edit toolbars and the page controls (toolbar)

The exceptions to the above can be found with [all[shadows]prefix[$:/core/ui/Buttons/]search[actions=]] and each of these handled separately, ideally to bring them inline with the same approach.

See also in the original post Extending this concept later


I can produce an example using the Generic actions you point to.

I would then like to see if the enabling macro (or a version of it) will be accepted into the core say in the pre-release.

Please help me more this change forward.

I would then modify all the core buttons in scope and offer them for inclusion in the pre-release.

Do I need to take account of

via keyboard shortcuts or any other place where the UI deletes tiddlers.
In this first submission?

Perhaps you or others can suggest how to extend this to shortcuts etc…?

I am keen to see this happen and are looking to find the shortest (safe) path to acceptance simple to have the buttons include
actions=<<button-actions "buttonname">> or perhaps as suggested more generic eg actions=<<tagged-actions "actionname">> with ‘virtual’ tags of the form $:/tags/Actions/actionname

I am happy to put the work into modifying every appropriate button, but of course want acceptance actions=<<tagged-actions "actionname">> and its dependence the macro.

So I would be interested in having this or equivalent macro in the pre-release;

Edited and not tested

\define tagged-actions(actionname)
<$list filter="[tag[$:/tags/Actions/$actionname$]]" variable=action-tiddler>
   <$transclude tiddler=<<action-tiddler>>/>
;Action tags in use
<$list filter="[tags[]prefix[$:/tags/Actions/]]" variable=action-tag>
   <$macrocall $name=tag tag=<<action-tag>>/>

only the macro is required.
I can write the documentation for the macro as well.


I Just realised this solution, via tags is a form of cascade that is not only the first, its all so tagged.

This makes me wonder if a similar mechanism could be used in a filter, a form of the “Lookup” operator. Perhaps if the lookup operator could be provided a filter

\define include-tiddlers() [all[shadows+tiddlers]tag[$:/tags/mytag]]
{{{ [lookup<include-tiddlers>] }}}

An the cascade like first behaviour emulated

\define include-tiddlers() [all[shadows+tiddlers]tag[$:/tags/mytag]first[]]
{{{ [lookup<include-tiddlers>] }}}

Please note the lookup operator returns the text field of found tiddlers, effectively a transclusion.

  • Its parameter is a prefix but could also treat a filter (starting “[”) differently.
  • Lookup can be used with no parameter for all tiddler titles fed to it.

I’m afraid it’s too late to get this into v5.2.1. We recently found a bug with drag and drop and the latest Chrome which is serious enough that we now need to more to the quickest release of v5.2.1 that we can. See this ticket:

I think that the changes here have significant complexity because they cut through a number of subsystems, and have wide implications. Realistically they will need to be done by an experienced core developer. No doubt something very like your macro would still form the core of the implementation.

The way I’d put is that this is an example of the well established “tagged items” pattern, which we also use for $:/tags/ViewTemplate tec. The “cascade” pattern builds on the top of the “tagged items” pattern, adding the cascade through each filter.

I’m not sure if I’m understanding your proposal. The easiest way to lookup the first match of a tag would just be:

<$transclude tiddler={{{ [all[shadows+tiddlers]tag[$:/tags/mytag]] }}}/>
1 Like

This puts me in mind of previous conversations around a core wikitext alternative to current JavaScript hooks, as part of the refactoring of the navigation mechanism to make it more customizable and wikitext based.

As you say, such a change needs to be made keeping in mind wider implications - ideally along with the refactoring of the navigation mechanism - lest we introduce changes that will constrain those future improvements.

@jeremyruston and @saqimtiaz I defer to your experience and understanding of the ramifications but as I understand it, this solution would be one of the least disruptive, I could imagine.

Fine, I am not arguing that it should delay a new release, but I could put the button modifications together in an hour or so, and the main “effort” is the minor alteration to every button. The next release could even be without the matching macro, just the actions=<<macroname actionname>> on buttons with no action parameter only (the vast majority) , then macro or a user defined macro will need to be installed, even separately as a plugin to do anything. In fact even this type of change has already being demonstrated on other core buttons.

Arguably only adding the action=<<tagged-actions actionname>> which would match the button name need be done, because this obviates the need to overwrite any button (or core tiddler in the future), just add a macro defined as desired, to attach new actions. If this change were made we could then have plenty of time to test perfect the macro. Since the action name follows from the buttonname perhaps it is only the choice of macro name tagged-actions that perhaps needs to be considered ( tagged-actions can not be found in tiddlers, system or shadows with advanced search)

Nothing occurs unless one if these "virtual tags’’ tags is used.

  • Each button existing would be modified to include a macro call with a parameter of the action name. Again nothing will occur unless there is a tiddler with that tag specific to its invocation.
  • Thus with both the macro and the buttons modified nothing beyond the macro invocation that results in, nothing will occur.

I will leave it to you to judge this, but if not now, Perhaps I should prepare it somehow for the next pre-release?

The complication arises from the number of other subsystems that will require analysis and potential modification – such as keyboard shortcuts. We also need to carefully define how the default actions are performed, and devise a way to suppress them if required. We will also need to add tests with decent coverage so that we can guard against future regressions.

Stepping back, the approach we have to take with core development is to consider every proposal in the widest context, particularly including other changes that we are considering in the same area. As @saqimtiaz notes, we intend to refactor the navigation mechanism so that it is implemented in wikitext instead of JavaScript, making it much more hackable and extensible. Actually writing code is a surprisingly small part of the effort.

1 Like

@jeremyruston so then the main issue here is if you are persuaded of the value and the mechaisium and you can wrap it into related work in the future?

In other words can you regard this as a request (not an issue or PR) and slip it in at an appropriate time?

This seems thus to be an example of another way to interact with core development. A Request submission process that is not a PR, for inclusion when permitted. If we could submit such things with confidence they will be addressed it could help all parties.

Until then I will publish a package that overwrites core buttons to test.

@TW_Tones I think the most beneficial thing to do at this point - and the best way to ensure eventual follow up - would be for you to update the related issue you have on Github with any changes in your proposal as presented here, and a summary of the ensuing discussion.

Dividing the conversation over mediums is likely to result in this being overlooked when reviewing what to work on for future releases. Issues (which can be requests) and PRs is how core work is tracked, and the more self-contained an issue is, the more likely it is to be addressed.

@saqimtiaz will do, I will revisit GitHub, but last time I looked the original Issue could not be found.

In this case the basic change is a minor change to more than a dozen tiddlers, must I do that for each tiddler (I hope not).

The following link gives a list of issues you have created, which can then be searched further:

Issues are for bug reports and discussing ideas, there is no concept of making changes to tiddlers. One issue for one idea. Furthermore there is no need to post changes to any tiddlers.

The key is not to split discussions across multiple mediums and keep the issue up to date and self contained, as in practice that is what gets considered when looking at what to work on - not discussions linked to from elsewhere. The discussions contained in this thread are now missing from the Github issue, therefore my recommendation to not only update your issue with any changes in your proposal, but to also post a summary of these discussions.

In general, issues for new ideas are more helpful and more likely to be followed up on if they are clear and concise, and focus on presenting an idea or a request, rather than the details of the implementation of the idea (the code).


@saqimtiaz There’s a HowTo hiding in that post.

Want your brilliant idea turned into a TiddlyWiki Feature?

Follow the FRIP!

The all new Feature Request and Improvement Protocol

blah blah

In general, issues for new ideas are more helpful and more likely to be followed up on if they are clear and concise, and focus on presenting an idea or a request, rather than the details of the implementation of the idea (the code). ~ @saqimtiaz

Or something like that.

The only metric I have is my own sensibilities, but it seems to me, since the advent of TWTalk, the ideas abound, overflowing across media as you intimate.

@boris Again, move this out if needs be.