How to safely customize the fields section of the edit template

I was looking to customize the edit template, and in particular, the fields section, but only for tiddlers with certain tags.

Looking at the available cascades, I see there is a Field Edit Cascade which allows you to provide your own template for the input of each single field.

The customizations I want to do include:

  • Disable the delete button under certain conditions (alternatively, make the delete button empty the field value, without deleting it)
  • Conditionally display text underneath the input widget (requiring enough formatting to make the entire table row taller, to accommodate this additional text)

As far as I’m aware, these things cannot be achieved through the field edit cascade. Thus, I’m looking a level higher.

I see that the Edit Template is tagging the following: $:/core/ui/EditTemplate/fields

Using this tagging mechanism, I can add my own components before or after the fields section; however, I want to conditionally replace the fields section. While I would like to do that on a per-field basis, I am okay with replacing the entire thing.

This seems fairly achievable by the following steps:

  1. Make my customized field editor tiddler $:/myFieldEditor
  2. Make a tiddler $:/myFieldEditorPicker that transcludes $:/myFieldEditor under the conditions I want it to (for editing tiddlers with certain tags) and transcludes $:/core/ui/EditTemplate/fields otherwise. (I think I could even make my own cascade to achieve this.)
  3. Add the tag $:/tags/EditTemplate to $:/fieldEditorPicker and add list-after: $:/core/ui/EditTemplate/type
  4. Remove the tag $:/tags/EditTemplate from $:/core/ui/EditTemplate/fields

This seems very reasonable, except for that I would have to edit the shadow tiddler $:/core/ui/EditTemplate/fields to remove the tag. If that tiddler gets updated in a later version of TW, then I would not get the updates when I upgrade my wiki because they will be overridden by a modified version of the old version. From what I understand, that’s why it’s recommended that you never override shadow tiddlers that form core ui components.

But is this really a bad idea? I get that if I modify the text field, then it could be difficult or impossible to merge changes; but in this case, since all I’d be doing is removing a tag, I could simply update the wiki, delete that overridden tiddler, and modify the shadow tiddler to remove the tag again, right?

But on the other hand, if I make my tool available to other users, then putting that burden on them might not be a good idea. (Maybe I could do something similar to the banner telling the user to save and refresh the page after messing with JS tiddlers, but have the banner tell the user to click a button that deletes the overriding tiddler and then recreates it by deleting the tag from the shadow tiddler?)

Thoughts?

Got one of the key things to transclude wrong in the idea, and have edited to correct it.

Although we avoid modifying core tiddlers, the system tag mechanisms, the cascades and other hackability features are there when we want to make changes to the default behaviours. These may make small changes to core tiddlers which we may consider acceptable.

  • There are various ways to implement such changes so that they have less impact and don’t hide future upgrades. Although your custom solution may itself not change, it will most likely keep working after an upgrade.

It is also worth exploring a little further to see if tiddlywiki already provides a mechanism to apply your “hacks” in a less intrusive way.

  • In this case one approach is a config tiddler $:/config/EditTemplateFields/Visibility/fieldname set to hide.

I think your idea to;

can be considered differently. Rather than “replace” what about simply not showing nominated fields in the standard editor, but do show them in your custom editor?

  • There is already a mechanism that hides fields from the standard editor, for example you can not see the text, created/creator and modified/modifier fields in the field editor.
  • See $:/config/EditTemplateFields/Visibility/text set to hide, this stops the text field appearing in the editor fields area.
  • eg Create a tiddler $:/config/EditTemplateFields/Visibility/dummy containing hide and the field dummy will no longer appear in the field editor. You can then create a separate editor that only shows the dummy field editor if its visibility is set to “hide”, and any other conditions you want.

Other related tags

  • SystemTag: $:/tags/EditTemplate
  • SystemTag: $:/tags/EditorTools

Personally I am very keen to provide more generic tools for designers such as yourself, to make more advanced use of custom fields and field editors. I have a lot of ideas and proof of concepts I just need to justify the time I need to spend on this.

  • It is always more time consuming when designing and documenting solutions for a broad audience and different levels of experience than it is to learn the tricks for my own use.
1 Like

I want my customizations to only apply when editing tiddlers with certain tags. If I mess with $:/config/EditTemplateFields/Visibility/fieldname, then it will hide those fields even when editing tiddlers that don’t have those tags.

I’ve come up with another idea, where I would use the story cascade to use a custom edit template under the conditions I desire (that is, if the edited tiddler has certain tags).

  1. The custom edit template would begin with \import $:/core/ui/EditTemplate (to make the macros defined in the default edit template available in the custom template). These will automatically reflect any changes to the macros due to a version upgrade.
  2. Copy the non-pragma content of $:/core/ui/EditTemplate into the custom edit template. (The most important part of this is that additional variables are set with the <$vars> widget and made available to the components of the default edit template.) These will not be automatically reflect changes due to an upgrade.
  3. In the custom edit template (which at the moment is essentially just a copy of the original one), modify the filter that transcludes everything tagging the edit template tag, so that it transcludes only what I need it to transclude. (Probably best to do this by creating a config tiddler listing tiddlers that, although tagged with the edit template, are to be excluded from my custom template - in my case, $:/core/ui/EditTemplate/fields - plus a tag to add additional components to the custom template and not the original.)
  4. Create a new tiddler containing a filter that adds the custom edit template to the story cascade for drafts meeting whatever conditions require the custom edit template (in my case, having a certain tag), but lets the cascade pass on to the next step (the default edit template) otherwise.

Supposing anything changes in a future version of TW, the \import will ensure all the macros, even new ones, will be available to the whatever edit template components I don’t remove. Additionally, they will not remove any variables defined in the <$vars> because that would be a breaking change for any customizations that added components to the edit template that used those variables.

What could potentially be a problem is if they added variables in the <$vars> widget to make available to the edit template components, and updated the core edit template components to use that variable. Because in that case, in my custom template which transcludes some core edit template components, those new variables are not available to the updated core components which need them.

Edit:

It appears I could also do this by using Hidden Setting: ViewTemplate and EditTemplate rather than the story cascade. I feel a cascade is more suited because I only want to conditionally customize the edit template (which is what cascades excel at, conditionally using different templates), but I could always set the hidden setting edit template to a tiddler that conditionally transcludes either my custom edit template or the default edit template according to the conditions I need.

I try and make my code be as minimally complex as possible. Rather than use separate tags I would use the existence of the field to determine the editor for the field, this is because fields are part of a tiddler, would you have these additional fields on other tiddlers?

Your above approach seems appropriate if it works for you, but as I think you can see there are a number of alternative approaches, and cascades that are relevant, the Edit Template Body, Field Editor and even via a story tiddler cascade.

  • I think the way to choose this is how large a scope of the changes you wish to make, and choosing the smallest.
  • For example if you want a special editor for a special field, only where it appears, then use the Field Editor cascade.
    • Within this you can choose to alter the behaviour depending on other conditions like particular tags otherwise use the default editor.
    • Only use the visibility setting if you want to hide a field editor in all tiddlers, making it dependant on your separate custom editor.

One technique that can help with safely overriding core templates is for the overriding tiddler to transclude the original core tiddler:

<$transclude $tiddler="$:/core" $subtiddler="$:/core/ui/EditTemplate/fields"/>

This technique isn’t perfect: for example, if two plugins try the same trick then only one of them will work. However it does protect against the future core update problem.

1 Like