Hello Stuart, I guess, since the plugin is small and somewhat simple, this is a proper task for AI :)
Here's
my take on this. Below is the result (I've amended metadata a little – changed plugin name). I haven't reviewed the whole code, but tested it, and it works fine.
/***
|Name |ToggleMultiTagPlugin|
|Description|Makes a checkbox that toggles several tags in a tiddler at once|
|Version |3.2.0|
|Date |06-Oct-2025|
|Author |Modified by ChatGPT (based on Simon Baird’s ToggleTagPlugin)|
|Source |https://chatgpt.com/share/68e3898f-91cc-8003-a697-d8ecafbc3b2a||License |http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Usage
{{{<<toggleTag }}}//{{{TiddlerName 'LabelText' TagName1 TagName2 ...}}}//{{{>>}}}
* TiddlerName — the tiddler to toggle tags in (default = current tiddler)
* LabelText — text (wikified) to show next to checkbox (default = list of tag names)
* TagName1, TagName2, ... — one or more tags to toggle at once
(If a parameter is '.' then the default will be used)
* TouchMod flag — no longer needed; config.toggleTagAlwaysTouchModDate still applies
!!Examples
|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles default tag (“checked”) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag MyTiddler 'click me' tag1 tag2>>}}}|Toggles both “tag1” and “tag2” in “MyTiddler”|<<toggleTag MyTiddler 'click me' tag1 tag2>>|
|{{{<<toggleTag . 'important tags' important urgent>>}}}|Toggles tags “important” and “urgent” in current tiddler|<<toggleTag . 'important tags' important urgent>>|
!!Notes
* Checkbox is checked if all listed tags are present
* Clicking adds all tags if any are missing, removes all if all are present
* If the tiddler doesn’t exist, it will be created (if createIfRequired is true)
* Set label to '-' for no label
***/
//{{{
if (config.toggleTagAlwaysTouchModDate == undefined)
config.toggleTagAlwaysTouchModDate = false;
merge(config.macros, {
toggleTag: {
createIfRequired: true,
handler: function(place, macroName, params, wikifier, paramString, tiddler) {
var currentTitle = tiddler ? tiddler.title : '';
// New order of parameters:
// 0: TiddlerName
// 1: LabelText
// 2+: TagNames
var title = (params[0] && params[0] != '.') ? params[0] : currentTitle;
var label = (params[1] && params[1] != '.') ? params[1] : null;
var tags = params.slice(2);
if (tags.length === 0) tags = ["checked"];
if (!label) label = "[[" + tags.join("]] [[") + "]]";
label = (label == '-' ? '' : label);
var theTiddler = (title == currentTitle ? tiddler : store.getTiddler(title));
// Determine checkbox state: true if all tags present
var allTagged = theTiddler && tags.every(function(tag) {
return theTiddler.isTagged(tag);
});
var cb = createTiddlyCheckbox(place, label, allTagged, function(e) {
if (!store.tiddlerExists(title)) {
if (config.macros.toggleTag.createIfRequired) {
var content = store.getTiddlerText(title) || "";
store.saveTiddler(title, title, content, config.options.txtUserName, new Date(), null);
} else {
return false;
}
}
var targetTiddler = store.getTiddler(title);
if ((config.toggleTagAlwaysTouchModDate) && targetTiddler)
targetTiddler.modified = new Date();
// Toggle all tags together
tags.forEach(function(tag) {
store.setTiddlerTag(title, cb.checked, tag);
});
return true;
});
}
}
});
//}}}