So you want to protect a tiddlywiki from a developer writing code without maintaining referential integrity?
Most users do not revert to code when using a solution you built, you can ensure that all uses of the delete action in the user interface handles this. See my all button actions solution.
But to do exactly as you ask see below;
For the hook you are looking for tiddlywiki may already have the tools for you to trap even new code being introduced; Have a look at;
Both allow you to trap one message and invoke additional or alternative actions in their place.
To achieve this, use either of these widgets and wrap the code within which it will catch calls to a given message. Thus you may wrap the whole story, and or the page template.
A more targeted approach may be to use the cascade mechanism to wrap only tiddlers with a particular condition eg; has a field object-type[dbrecord]with a message capture. Whole of tiddler will catch the buttons, on the tiddler.
define renameThisTid(tid newName)
<list thisTid filter="Get tiddlers that have $tid$ in a particular field">
set the field to the $newName$
</list>
rename $tid$ with $newName$
if that didn't work for whatever reason, then
<list thisTid filter="Get tiddlers that have $newName$ in a particular field">
set the field to $tid$
</list>
end
button actions="""<renameThis <<currentTiddler>>> NewTitle"""
Rename this task and related tasks
/button
Install the relink plugin, which arguably could be in the core, and add the “arbitrary field” in which you want “titles” updated whether it can contain a single title or a list of titles.
I am not 100% sure how viable it would be to replicate what my JS is doing with MessageCatcherWidget – my JS uses th-saving-tiddler hook (not a message). It should be possible but…
It won’t work in the context I mentioned earlier - I am writing a plugin. While I can technically shadow a core tiddler to use this widget it has this one big problem: only one plugin can do it at a time. And that assumes the TW user didn’t shadow that same core tiddler themselves.
So while MessageCatcherWidget is a great widget I didn’t know about before it still isn’t as versatile as required to use it in a plugin to improve data integrity. Unless, of course, there is a way to stack those across multiple plugins that can’t be accidentally shadowed by the TW user themself.
I am painfully aware of what XY Problem is and this is not the case. I know covering these cases might never pay off but I am still going to do so, be it with JS or not.
I didn’t understand all the intricacies of this thread but if the quoted bit here is what you’re after then, yes, you can target specific tid titles with CSS to hide stuff in only those.
As you have correctly surmised there are currently no wikitext affordances for using hooks. The message catcher widget intercepts widget messages, which are distinct from hooks.
Third party plugin dependencies are indeed a pain point, especially in the absence of a cross-library dependency resolution mechanism during plugin installation.
I was actually developing a plugin that would work a bit like global keyboard shortcuts at some point in the past but responding to hooks, but lost interest.
The solution I have been using privately is a very simple plugin that executes tagged tiddlers with a given tag for each hook, setting the appropriate variables. This works for most though not all use cases, such as those where you need to access properties of JavaScript objects. However, with the introduction of JSON operators in the core, this can now be further improved.
At some point we will want to introduce wikitext affordances for hooks into the core but this likely needs to happen hand in hand with a refactoring of the navigation mechanism to which much of the handling of hooks is currently tied.
Edit: here is an extremely early and limited version of executing actions from tagged tiddlers in response to a hook, that I baked into a plugin.
I think this assumes you are using a plugin to introduce Javascript and you want to do the catching within that plugins javascript. A plugin can just include standard tiddlers that introduces the message catcher to the wiki as a whole.
That is you are right “It won’t work in the context” you are using but, “will in the context I am suggesting”.
As this indicates that same ultimate solution can be achieved with widgets.
My serious concern is if javascript hooks are developed to solve problems that we should solve in the core wiki text / widgets we force future solutions to use hooks. This locks out non-javascript solutions.
Ideally we first handle it in Wikitext and Widgets and then also introduce it for the more sophisticated JavaScript plugins. The two can and should co-exist but obvious, fundamental and required functionality, such as ensuring referential integrity, belongs in the core and accessible via widgets and messages.
I have no idea what you are referring to. @Maurycy has expressed needs that cannot be satisfied with widgets. If you feel otherwise please provide a concrete example of how it would be accomplished.
I suggest reading my later replies more carefully, which focuses on the introduction of wikitext affordances in response to what are currently hooks only usable from JavaScript. These hooks already exist in the core and have for quite some time.
Adding core wikitext affordances for hooks isn’t a new topic and you have been involved in discussions around it as well. I would think that you would welcome this, as it extends the possibilities of what can be accomplished with wikitext.
This is an position I do not agree with, unless you confine it to Javascript.
I think it not only appropriate but a duty to question claims I am confident are wrong. An assertion of truth is not necessarily the truth.
What you have said may be true in a specific context, I argue it is not true in another.
Like wise, read my extensive content - starting with TiddlyWiki as a modelling tool - let's discuss that led to this thread and my assertion that the OT and referential integrity does not need hooks to solve, even if there is value obtaining these hooks.
keep in mind I am calling for more discussion about the details of perceived gaps because I believe I have a full suit of solutions.
There remains a prolific reversion to Javascript when native TiddlyWiki can already do it and if and when we can establish a gap we need to remedy it in tiddlywiki not by enabling bespoke plugins.
When this is the case it is advisable to ask questions of clarification and consider if you should say anything at all. I believe you have already taken me to task in the past for stating “I have not had the chance to read the full thread”, I hope this is not an example of the same thing but without saying you had not read it?, I would have thought the issues would be clear if you read the thread in detail, and you would also See @Charlie_Veniot is of a similar view.
The sad thing is I stated very early
So it is disappointing it takes so much effort to disagree, and put an argument that others are contradicting. I only want an exchange of ideas, not subject to people piling in and supporting their tribe.
I have read the entirety of the relevant threads, though in the latter part of this thread you limited the scope of the discussion by asking Maurycy to provide a concrete example of something they want to accomplish, one of which you see below. So let us focus on that one particular requirement.
So can you please explain how the below requirement can be accomplished with widgets, so that it is always true in a given wiki? There are no widget messages generated by the action widget in question.
Likewise, it is very frustrating to see fellow community members being easily triggered and assuming the worst when confronted by potentially unfamiliar things, when one is devoting time to discussing the limitations of wikitext and further empowering those very community members in terms of what they can do with wikitext.
Please don’t make this personal, challenge the ideas not the person. Adding a degree of humility and compassion is warranted to handle disagreement.
To understand is a different matter.
Because the conversation continued to be a cross purpose, and was too generalist in nature while drawing a specific conclusion.
I have pointed out a number of ways to achieve this via intervention in User interface elements, catchers and more;
If someone decides to revert to building there own trigger and actions such as <$action-deletetiddler/> then they are choosing not to use that provided by the solution provider.
If the designer provides the correct tools and document them people will use them.
If the designer intercepts at a lower level an attempt to use an action, such as delete, you limit the customisability and ease of understanding of your solution, perhaps even damage the ability for someone to repair a broken wiki.
What percentage of users would adopt a solution which provides referential integrity, then go ahead and do things with action widgets that put that integrity at risk?
Except that none of the suggested options actually respect the given constraints, i.e. a plugin that can robustly interoperate with other plugins in the same wiki, without third party dependencies. Arguing the merits of the constraints is fair but it is not the same as providing a solution for them.
Overriding user interface elements is inherently brittle in a wiki that might use other plugins that may also do the same, or provide alternative UI affordances for deleting a tiddler. Every single user that used another plugin and/or wikitext code provided by someone else would potentially be at risk of running into problems, even if they themselves never directly used action-deletetiddler.
The MessageCatcher and EventCatcher widgets cannot intercept hooks or the action-deletetiddler widget. It was the advice to explore this option that prompted me to participate in this thread, so as to save anyone the trouble of exploring this dead end. Neither can either of these widgets be used to capture messages or events in the entirety of a wiki without overriding shadow tiddlers, another point of brittleness for a plugin that aims to interoperate smoothly with other plugins.
The advice to use Relink neither addresses the need to respond to the action-deletetiddler widget, nor the desire to avoid third party dependencies which can be a failure point. My experience with Streams has been that despite documentation, the dependency on Relink is the most common failure point for users, to the extent that I had to start distributing Relink alongside Streams in the same plugin library so that it would be automatically installed.
So is there a valid solution for intercepting action-deletetiddler within the given constraints that I have missed?
A heads up that Streams does this, so you may want to take that into account for any potential future usage of the plugin.
I am personally of the opinion that implementing features with robust tiddler relation handling are best done through bespoke TiddlyWiki editions that are heavily customized and not necessarily marketed as interoperable with all other plugins and customizations. Constraints can often lead to a better and more robust user experience.
However, I think it is an admirable goal to try and write plugins that can interoperate with other plugins and be robust and usable in a standard empty TiddlyWiki, and we should try to encourage and support this wherever possible. I would be happy to participate in any further discussion around how we can do so in practice for better handling tiddler relations, rather than debating the merit or need for such an approach.
Identifying the current limitations of wikitext is important as it allows us to understand where the core can be improved to allow greater flexibility and customizability via wikitext, ultimately further empowering TiddlyWiki users.
The context has nothing to do with requiring JS and all about supporting most scenarios I deem reasonable (and talked about from the get go):
I have a plugin, for the sake of the argument let’s say it’s my Task List plugin
This plugin creates **Relation **tiddlers that are linked to User tiddlers.
I want to achieve:
Req 1:Relation is deleted when User tiddler is deleted
Req 2: Field linking Relation to User tiddler is updated with a new name when User tiddler is renamed
Req 3: It must work regardless of how user triggers the deletion or rename.
MessageCatcherWidget is ruled out by Req 3 because it won’t detect events triggered by global keyboard shortcuts
And there may be other edge cases where it wouldn’t trigger than I can’t think of at the moment
I don’t want to shadow core tiddlers to modify the UI:
Multiple plugins can’t combine their changes to the same core tiddler
Which rules out MessageCatcherWidget immediately
These changes can be overwritten by the user themself
Must be kept in sync with TW updates
This rules out any modifications to the UI to make it more difficult for user to do things accidentally
I don’t want to use cascades to have custom rendering for the tiddlers to block delete buttons
It’s not custom-layout friendly
Requires duplicating core wikitext and then maintaining if you want things to look the same
It doesn’t cover Req 3
Releasing the plugin as an edition with customized everything won’t work:
It no longer is a plugin and becomes useless to anyone who would like the functionality in their existing wiki
Still doesn’t cover Req 3 unless I also modify JS, in which case I can just have a JS hook in my plugin
I don’t want to include another plugin
Don’t want to bloat user’s wikis
Needs to be kept up to date
I don’t want to add dependencies when they are not needed
Relink plugin wouldn’t cover Req 1 and I am not aware of a plugin for that (which I could also write but see the 3 points above)
The included plugin would still need to use JS to satisfy Req 3 in which case I can just have a JS hook in my plugin
I talked about Req 1 and Req 2 right in my first reply in this thread.
I talked about my reasons to not want to customize the UI in a plugin in my second reply in this thread.
I even mentioned I already use cascades to some extent in another one.
I am very bad at translating thoughts from my head to text especially if it’s longer than a few sentences and get very easily lost following bigger conversations that I am part of. I apologize if all the misunderstanding came about because of my poor communication, I can’t really tell why this happened. This thread has spiralled out of control and I am out of it now.
The main problem is, that relinking only happens with “tags” and “list” fields by default. What we want imo is an additional parameter that also allows us to relink with list-like fields.
<$action-sendmessage $message="tm-relink-tiddler" list-fields="test [[list with spaces]]" from="Tiddler1" to="Tiddler2" />
IMO the change to the core should be relatively straight forward. At the moment it’s locked to tags and lists. … With the additional parameter it would be extended to other “list-like” fields.
IMO for simple usecases, this may go a long way already.
BUT
I think the mechanism that Saq suggested should be much more flexible because it gives to control to the user instead of providing a “hardcoded” workflow.
The code involved isn’t too complex, so there should be a chance to get it merged.
An important thing to keep in mind is when you come across a limitation in tiddlywiki for some systemic function we all want to use, or we want to be able to write plugins that are compatible, the answer is not bespoke solutions, but contributing to the core and adding the required tools and hackability so we can all get the results we need.
This is no more than the case discussed here, relation handling.
This approach to tiddlywiki development has persisted throughout its evolution.
There are half a dozen examples of how we add hackability to tiddlywiki that are useful, backwardly compatible and allow multiple plugins to leverage.
For example rather than add an additional UI layer to my wikis I discovered the existing buttons and navigation are ideal places to intervein, so I demonstrate improved hackability by using tags to add additional actions to any button. https://all-button-actions.tiddlyhost.com/ I would recommend this or a version of it be added to the core.
Yes the delete process may be a gap but lets fix the gap, and add hackability to it. It is a gap, in my “All Button Actions” because of the cancelation process. yes we could have the ability to catch a delete tiddler, message.
There is a strong argument that the relink plugin should move to the core plugins, if not the core. It is better to add that as a dependence that reinvent it and possibly create a clash.
I appreciate the value of the contesting of ideas, but sometimes it is quite tiring when people work hard to reject your argument, rather than try and find out another persons perspective.
When discussing design approaches there are “value judgments” involved and unless people are openly receptive to other views it can be hard work communicating.
Perhaps I have already said what I needed to say, I can’t help that not everyone will understand it, although I tried, especially not those who think they already know it all (I am not implying/accusing anyone of this).