No touch tags - or flags on tiddlers without editing or changing the tiddler

Perhaps but I considered it related. The difference being, that titles in the flag-list, do not become backlinks/missing tiddlers. Is there a solution for both flag tiddlers using flag-list and those using the proposed text field?

Agreed, it is, in the context of here

So I remain baffled why you dismissed my analyse of it in this context, as if it was irrelevant.

(FWIW, I think it should be it’s own topic because while everything you’ve said about it here makes me think it’s wrong for flags, I still think the idea as an independent proposal is worth discussing)

I am miles away from knowing enough about TW in general to know what could be done or how easily. My idea of what feels (to me) in keeping with existing TW is already noted above, ie,

This is the question. Given the way the text field is currently scanned for tiddler links, and made available as existing titles, be they missing or not. Can we have other fields, nominated or found, be used as a source of hard links?

  • If possible we can use this to make the flag-list and other fields generate hardlinks/missing tiddlers
  • If not possible the creation the the link tiddler concept may need to leverage the text field.

I think it would be difficult or impossible to do this in wikitext right now. But I’m fairly certain that it would be a relatively easy change to the core, assuming what we want to do is to add the names of some additional list fields to search for the entire wiki. We could look for a tiddler like

title: $:/config/LinkSearch/FieldNames

tid-list
related

and use it to search for additional hard links, whether present or missing in those list fields.

This would be entirely opt-in. The text field would always be searched, but if this tiddler was present, we would treat its text field like a filter, and use the results of running that filter as a list of additional field names to scan. There would be no default for this tiddler. If it’s not present, we search only the text field. (So more like $:/config/SaveWikiButton/Filename than like $:/DefaultTiddlers.)

Does this sound like it would meet the needs?

1 Like

A collection of general thoughts, as I’ve only been loosely following this thread:

  1. First, a question for @TW_Tones et al.: Practically speaking, is the flags system (as proposed in this thread) essentially just an alternate approach to tagging? I understand that one of the primary motivations was the desire to modify the behavior of system tiddlers without directly modifying any shadow tiddlers1. Do you have any other concrete use-cases in mind?

  2. I’m personally reminded of @Mohammad’s Favorites plugin, which was designed to fill a different need but has a similar underlying structure. Here’s a sample “folder” from his demo, where we can see…
    a. A tag used to mark each collection of titles, $:/tags/Favorites/Folder — akin to @TW_Tones’s flag tag.
    b. The list field contains all the user-selected titles that belong to this grouping.
    c. The text field is reserved for normal use; it’s displayed in addition to the ViewTemplate segment that adds the “folder” view. This means that (while Mohammad isn’t showcasing this function) you could theoretically turn any normal content-carrying tiddler into a Favorites folder just by adding the tag — though you probably wouldn’t want to use a tag tiddler as a “folder”, since both systems (potentially) use the list field.

Out of the box, I don’t think Favorites can be used exactly as we’d want this potential flag system. For one thing, it’s currently built on the assumption that “favorite” tiddlers belong to no more than one folder (though this could be a limitation of the drag-and-drop UI more than a deliberate design choice?) whereas you might want to give a tiddler more than one flag. My ideal “putting things in ad-hoc groups” solution would be more flexible in this regard.

However, I do think the Favorites interface is well-designed and inspiring, and it makes some choices I’d certainly hope to see in “Flags” — particularly the use of a list field rather than the text field for title storage.

  1. If the goal is to avoid modifying shadow tiddlers, I don’t think “Flags” goes far enough.

This may be a controversial suggestion for this thread, but what I’d ideally want (if we’re modifying core anyway) isn’t an alternate approach to tagging in particular, it’s a way to functionally overwrite select fields without “un-shadowing” a tiddler.

Upthread, @Springer suggested modifying the filter field of $:/core/Filters/Missing

And in principle, I agree! TW has a number of these “filter” fields that feel as if they’re designed to be edited. But doing so will turn a shadow tiddler into a real one just as much as modifying the tags does — and again, you’ll be left with an un-shadowed tiddler without any clear indication of what has been changed. So the issue is the same: how do we modify the behavior of shadow tiddlers without touching them?

Here’s one pie-in-the-sky approach that makes sense to me:

  • Assume that every shadow tiddler has a hypothetical partner with a certain system prefix. (There’s some precedent for related titles already — see $:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/home vs. $:/core/ui/Buttons/home.) If we used the prefix $:/unshadow/, $:/core/ui/SideBar/Tools would be paired with $:/unshadow/$:/core/ui/SideBar/Tools.
  • If $:/unshadow/$:/core/ui/SideBar/Tools exists and has a given field like tags, that field is used in place of the tags field on $:/core/ui/SideBar/Tools. Essentially, we’d be overwriting a shadow on a per-field basis — and we’d be doing it in a separate tiddler.
  • Give users the option to clone-and-modify a field on the $:/unshadow/ counterpart rather than modifying the shadow tiddler’s fields directly. For instance, rather than removing the tag $:/tags/SideBar from $:/core/ui/SideBar/Tools, you’d give $:/unshadow/$:/core/ui/SideBar/Tools an empty tags field.
  • Allow TW to check for “unshadowed” fields and fall back to the shadow tiddler’s own field value if no alternative is found. If $:/unshadow/$:/core/ui/SideBar/Tools has tags: , $:/core/ui/SideBar/Tools doesn’t appear among the sidebar tabs — even if it’s unmodified.

Upsides:

  • It would be easy to display “unshadowed” fields on a shadow tiddler and delete them to revert changes on a per-field basis.
  • Probably some moderate reduction in file size: you’d only have to duplicate fields you wanted to change, rather than (potentially) every field on a tiddler, as currently happens when you modify a shadow.

Downsides:

  • Like the “flags” system, it would require some core changes. (IMO, these changes would serve a broader function while being somewhat less opinionated… though we would still have to choose an appropriate prefix.)
  • Performance implications? I have no idea.

In any case, I recognize that this is a bit of digression, but I wanted to present it as both an alternative to the “flags” approach and a potential solution to @Springer’s “general problem that needs a more general solution.”


1 As I understand it, if this system were adopted, we would in fact have to modify a number of shadow tiddlers to accommodate user flags — e.g. $:/core/ui/PageTemplate would need to replace

<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]]" variable="listItem">

with

<$list filter="[all[shadows+tiddlers]tag[$:/tags/PageTemplate]!has[draft.of]] -[subfilter<flag-list>]" variable="listItem">

where <<flag-list>> points to whichever tiddler/field is storing the relevant list.

4 Likes

Great stuff @etardiff!

I know this wasn’t aimed at me, but my take is that the goal is mostly to override certain features of any tiddler without actually changing that tiddler. So while core tiddlers would probably be a major use-case, it would also help with MWS’s bags-and-recipes design and with anyplace you have tiddlers you want to override but don’t want to touch.

I really do think this would cover pretty well all the use-cases we’ve discussed here. Moreover it would serve as a substantial first step toward solving the issue I discuss in Tiddlers with JS-prototype tiddlers.

I would prefer $:/override/.

Major caveats

I’m learning little bits of the core, finally, but still don’t have nearly the experience to answer this. But my suspicions are that this would be huge. Every get for any field would need to check not only the tiddler object itself, but also its overriding peer. I don’t know how well those could be cached in the object itself. If they can’t it would be much worse, but even if they can, it would turn code like

tiddler.fields[fieldName]

into something logically like this:

tiddler?.__peer__.fields[fieldName] ?? tiddler.fields[fieldName]

I don’t know whether the code for this is already centralized so that we can fix this in a single place, so I don’t know how much work it would take to implement. But it’s possible that it would be a fairly simple change.

My other concern would be about how to remove an override. If for instance, we overrode the text field, and later realized that we no longer wanted to do that, we can easily set it to an empty string, but we can’t easily remove the field. However, for, say, the tags field, we would want the empty string to override the existing non-empty one. I imagine would could find a UI that helps with this, but I think it’s at least a potentially serious problem.

So I like the idea, but I’m still somewhat wary of it.

1 Like

As would I! I knew someone would have a better suggestion.

This is my major concern as well. I’d hoped the issue might be somewhat mitigated if this were a shadows-only affordance — but this was largely because I couldn’t immediately come up with any scenarios in which I wouldn’t want to modify a standard tiddler directly. Your MWS use-case is a good one, and there may be other uses I hadn’t considered.

Why not? In my mental model, removing a field from an $:/override tiddler is precisely how you’d revert to the “base” field content — just as you delete a shadowed tiddler to revert to the shadow. I see it as resembling the distinction between !has[field] and !has:field[field]: a field that’s present but empty would constitute an override. So this would be distinct from get[field], where “empty” and “absent” are treated the same way.

Unfortunately, I don’t have the technical proficiency to look into this myself. I hope someone who does can weigh in.

Thanks as always for your thoughts!

1 Like

It’s not hard to come up with others.

Here’s a JSON bundle of data tiddlers: US_States.json (10.7 KB). They look like this:

title: US State/Alabama
tags: [[US State]]
abbreviation: AL
capital: Montgomery
largest-city: Huntsville
established: 1819-12-14
square-miles: 52420
numbber-of-reps: 7
number-of-counties: 67

title: US State/Alaska
tags: [[US State]]
abbreviation: AK
capital: Juneau
largest-city: Anchorage
established: 1959-01-03
square-miles: 665384
numbber-of-reps: 1
number-of-counties: 30

...

(with data cribbed from Wikipedia.)

You can import this collection into your wiki in the usual way. But you can also share it with another wiki, even if you’ve lost the original JSON file, by simply dragging the custom tag pill to the new wiki. This makes for easy sharing of data across wikis.

However, if you update US State/Alabama with last-visited: 1981, this data is no longer pure. It gets hard to share when the next person doesn’t want that field, but needs a state-flower one. And someone else wants average-SAT-score. The data diverges and is not easily shareable. But with this mechanism in place, we can easily do our extensions like this:

title: $:/override/US State/Alabama
last-visited: 1981
scenery-rating: 3

title: $:/override/US State/New Mexico
last-visited: 1982
scenery-rating: 8

and the original data remains pristine.

Sure, but at the moment, there’s no obvious way to remove the text field. Yes, we can add an affordance for doing so, but there’s a few fields that would be awkward to delete.

I do. (Probably.) But I won’t have the time for at least a few days.

That’s interesting, and I think it may suggest an underlying difference in the way we conceptualize the role of a “standard” tiddler. Personally, if I wanted to preserve a “pure” data set that could be shared between wikis, I’d package it as a plugin. And conversely, when I’ve borrowed tiddlers either between my own wikis or from others’ wikis “in the wild”, I’ve never been remotely concerned with maintaining a record of the original data — or, indeed, with shareability. I expect the data in a “standard” tiddler to adapt to the needs of the wiki in which it’s used.

On the other hand, one issue I’ve occasionally encountered is that while plugins offer a convenient method for packaging and sharing “pure” data between wikis, it’s less convenient to surface a plugin tiddler through standard search or even standard filters (unless you’re already in the habit of starting all your filters with all[shadows+tiddlers]). In this case, a package of standard tiddlers (with optional overrides) might be a good alternative to a plugin. That’s not a use-case that would have occurred to me, so thank you for the insight!

Ah, I think I see the point of miscommunication. You’re talking about UI methods for removing the text field in the current EditTemplate; I was thinking on a more theoretical level, where you can use $action-deletefield + a button to delete almost anything.

I do think a user-friendly override system would require some updates to the default editor. It would almost certainly require some extra buttons, but we’d probably also want to clearly highlight fields that were being overridden. Off the top of my head:

  • A button to create an $:/override tiddler for the current {!!draft.title} (perhaps only visible for non-shadow tiddlers, if shadows prioritize the override system by default?)
  • If an override exists (or if the tiddler is a shadow), display a tabbed field editor: the first tab corresponds to the override tiddler, the second to the “real” tiddler.
  • If no changes have been made, fields in the override tabs use the default attribute of $edit-text to display the value of the corresponding field on the “real” tiddler (or perhaps its draft?). This would let you start editing the override immediately, while also providing a live view of the “effective” field values.
  • Perhaps a $diff-text widget highlighting any changes? We already have this option in the text preview window; it would be nice to have it for “shadow” fields as well.
  • You could add and delete fields in the override tab as usual, with the caveat that deleting a field would restore the default value.

We’d probably also want to indicate any relevant overrides in the Info section of the ViewTemplate.

1 Like

I have no problem with this tread being expansive with related ideas.

Today I am trying to fix a fault in my solar panels, not sure how much time I will have here today.

I too have an interest in an additional cascade over existing tiddlers and shadows. However without giving you a full response @etardiff can you explain how your approach would deal with multiple plugins wanting to do the same thing?

  • core code that looks for tiddlers with a given tag is the most hackable method we have at this time. That is not tagging core tiddlers.
  • the flag model may help here too, but only once the core is coded to respond to such flags as is the current approach with system tags.

Although I did not elaborate my exploration of list tiddlers it was exploring mechanisms that may assist in some of these adjacent issues.

  • I did at length explore what I named ghost tiddlers not dissimilar to your idea, but different.
  • I think to achieve what you are suggesting we may want an additive process, and a subtractive one at least against list fields.
1 Like

Do you mean if, for instance, I installed multiple plugins that all included a different override for $:/core/ui/PageTemplate — that is, they all included a shadow tiddler $:/override/$:/core/ui/PageTemplate?

Honestly, I don’t have a good answer. I suppose I would expect the last version to win? This wouldn’t be any different from the current system, though (where, barring a non-shadow version, the last $:/core/ui/PageTemplate would be used), so I don’t think it’s particularly a downgrade.

How would your flags approach solve this issue? I apologize if you’ve explained this previously; it’s not coming readily to mind.

Good luck with the solar panels!

1 Like

I haven’t thought it through very carefully, as without this extension mechanism, it makes no real sense. But I needed a break from all the politics stuff I was working on last night. (I’m co-chair of my local Democratic Town Committee, and municipal elections are fast-approaching!) Creating that silly little states list was exactly the right 20-minute project. I don’t know that I would actually use states that way, but it might be a great way to deal with the lists of elements and compounds for my periodic table wiki. I’ll have to consider it more.

Yes, but I’ve spent no time imagining a design for this. Thanks for the start. It sounds like an excellent system. But I am worried about anything that steepens the learning curve for using TW. So I’m wondering if there is an alternative which makes a single up-front choice about whether this edit session is for a regular tiddler update, a shadow tiddler clone update, or an override update, and then everything happens on a single tiddler.


One more major caveat, also about deleting fields. Does an override tiddler simply set the value of a field to blank in order to override it? If so, are there places where this will cause problems? Because these two are distinguishable: has[xyz] and has:field[xyz]. What if we want our override to set the field value to the empty string? How do we distinguish between that and removing the field?

That’s the only thing I can see that makes sense.

Let me make sure I’m following…

  • Tiddler A has field foo: bar.
  • $:/override/Tiddler A has field foo: — that is, an empty field. (If the field’s not present, no override occurs.)

In this case (assuming that has and get and other similar operators look for override fields first) I’d expect [[Tiddler A]has[foo]] and [[Tiddler A]get[foo]] to return nothing, and [[Tiddler A]has:field[foo]] to return “Tiddler A”. This would make it functionally impossible to get [[Tiddler A]has:field[foo]] --> null if an override exists. Is that the issue?

It strikes me as a fringe issue, but worth pointing out. And I’m afraid I don’t have a good solution in mind.

In writing this, it occurs to me that we might also want additional suffixes for has and get — perhaps :original and :override to look only at the corresponding original/override tiddlers, rather than following the typical override → original priority list. So there would certainly be added complexity… :thinking:

I’m feeling ever less optimistic about the feasibility of this approach. Still, thank you for the reality check.

1 Like

Yes, that’s it exactly.

I think it’s likely a minor issue, but I’d want to know that the core, official plugins, and other popular plugins and editions don’t actually use that distinction. If they don’t, then it could be a documentation footnote. If they do, we have more issues.

Sorry. :frowning:

I do still have hope, although it too is somewhat diminished.

Part of the trouble is that what I’d really want is one large step further than this: the equivalent of nesting doll tiddlers, where an outer tiddler may have the field we want, but if not we check with the one inside it, and then the one inside that one, until we find it or run out of dolls. Jeremy explained in that thread why, although a possibly very useful approach, it cannot be added to the core. But I may one day try to get a version of it in userland.

1 Like

it does not solve the problem you pose, only demonstrates a no touch method. It needs further design.

I think I fixed the solar panels.

Today I pack for a house sit that starts tomorrow.

There may be some room to use the existing shadow tiddlers system, the last plugin wins but I wonder if we could provide more visibility and control of this process for targeted tiddlers. it is actually quite easy to move a tiddler into and out of a utility plugin. if we can read all versions of a shadow then we can see all variations and generate a synthetic tiddler. :thinking:

As Raised here Tip: Scoped Styling - #5 by TW_Tones I see that we have the core hackability relating to SystemTag: $:/tags/ClassFilters/TiddlerTemplate

  • This seems to be an opportunity to display on a tiddler a flag indicator without using a view template tag
  • However this feature is not well documented.

I just reviewed this issue, and one idea, which may be equivalent for you is redirection via transclusion.

If you get a field value through transclusion and that field has a transclusion in it, then it will keep transcluding multiple levels deep until if returns a value.

  • {{!!fieldname}} when fieldname contains {{parentTiddler!!fieldname}}
  • When the parentTiddlers “fieldname” contains {{otherTiddler!!fieldname}}
  • When the parent tiddlers “fieldname” contains a value it will return "a value’.

Of course this could be turned into a single filter cascade that looks at multiple locations until a value is returned, and one could make the tiddler names tested as programaticaly generated.

  • Moving it into a function even better get.fieldname[]

I would find this too heavyweight. It would mean that child tiddlers had to know and copy all the fields of their parents to add the transclusions necessary to follow through the chains. And if the parent changed, then all children would need updated.

This, on the other hand, is what I think would potentially work. It wouldn’t be just a single function. We would need extensions to the get operator, the $view widget, and many other things. The question is whether there is a relatively small core of these which the other could themselves call. I haven’t done any of that analysis, but I do worry that this would be quite a large undertaking. In that thread, IIRC, Jeremy mentioned some place where he’d done something like this Object inheritance, but I never looked deeply at it. When and if I do, I will be examining that closely.

Wether its light or heavy is realy dependant on meta issues. The children may not need updating.

However if such a field value cascade is going to work, there needs to be an identified logical pattern where to look. ie what ties the one or more tiddlers together.

  • Have you an idea for the cascade pattern in your mind?

I recently used a transclusion to invoke a template to replace headings here Table of Contents from Headers - #9 by TW_Tones lets say that we move the cascade to a tiddler such that a field value may contain {{fieldname||cascader}} and within the tiddler cascader was the logic to source the value from an established cascade, for example from the same fieldname in $:/ghost/currentTiddler then $:/default/currentTiddler and if nothing a default value.

  • Further work may allow the default to be provided in the transclusion {{fieldname||cascader|default}}
  • An importiant point is that transclusions can be nested, and a reference to transclude a field will work through the series of transclusions like other cascades.
  • keep in mind the currentTiddler will be the title in the transclusion, eg Fieldname, you can use storyTiddler to find the visible tiddler.

In this proposal a field is just a field with a value, unless that value is a transclusion. all be it accessed via transclusion or reference (not with a get in a filter). So in the “end tiddler” we can change the value that suggests you need to get it from elsewhere, elsewhere is resolved by the transclusion of a utility tiddler. eg the above cascader tiddler.

  • Think of this as giving the field a special value, one that can be sourced from a cascade.

I can give an example if you can answer;

Have you an idea for the cascade pattern in your mind?

[Post script]
The other approach is to reference the field value as a filter allowing the field value to contain the cascade filter itself.

  • Just as we have the ability to provide a custom field editor, we could do this to view or retrieve the field as well. Where that field contains a filter or transclusion (function or procedure) to resolve the value.