What's the deal with the WikifyWidget?

While there are occasions where the WikifyWidget is the right choice, it is generally recommended to instead use $let or $set if possible, because $wikify apparently taxes the system much.

I’m wondering… does it really have to be that way? I’m fully aware that I have a very naïve understanding of what the widget does but it seems to me that it “merely” turns calculated output into a plain strings… at least that is what I (always?) use it for. But I’m thinking the difficult part in that task is the first bit, i.e to “calculate output”, not the second part to “turn into a string”. I mean, the “turn into string” is pretty much what happens when you copy-paste calculated output and it loses its formatting. (Did I mention naïve?) And conversely, the difficult calculations as in, say, evaluating a filter… well, that is what $set and $let do, which is what we’re encouraged to use in stead of $wikify - !?

So, what’s the deal with turning some output into a plain string? Easy peasy for even a toddler, but evidently not for a tiddler!!! (Hey!)

Maybe $wikify has a lot of other power in it, and the way I use it - to “just make a string” - is a special but common use case, really underexploiting its power? If so, should there perhaps be some other, less system taxing, widget for that use case? Could, say, the ViewWidget or the TextWidget be made to store a reusalbe variable?

@twMat it is true that one gets mixed messages about the use of the $wikify widget, this is because it ties back to the whole structure and operation of tiddlywiki. To understand it, is largely conceptual. I will try and explain how I understand it and perhaps it will resonate with you. But first lets discuss the best work around.

Avoiding Wikify

The reason people often wish to use Wikify is to “evaluate” something within tiddlywiki and use this to alter the logic and output of their TiddlyWiki script. We have now being given the /function and the backtick “Substituted Attribute Values” which will be evaluated in line without needing to wikify.

  • Filters (within functions) give you access to tiddler, fields and variables allowing you to interogate almost anything.
  • Substituted attribute values can do the same, including references, using variables/filters and functions.

Filters have so many features, that arguably there is very little you can’t evaluate and there is no need to wikify.

  • If we find examples where we must use wikify, there is an argument we found a gap we need to address in the core.

What is wikify?

It is importiant to understand that the wikify widget makes possible something that is always happening in tiddlywiki and normaly at the very last moment.

  • Rendering - making the output into html to be presented in the browser
  • It is also importiant to realise the TiddlyWiki Script is not a procedural language.
  • Perhaps it is a declarative language?

Tiddlywiki takes text, wikitext and TiddlyWiki script and “eveluates it”, then converts it to html, and thus displays it.

  • Sure the widget allows more than this, but that is basicaly what its doing, although it has other utility functions
  • You can see from this, that wikification is the last thing before displaying things, so perhaps you can see how this is kind of problamatic, using wikify, you are doing this before hand, to alter the flow of your code.
  • Tiddlywiki needs to guarentee it renders and returns control to the user and ASAP.

I have struggled with this myself, but have come to realise some concepts that help me here. They are backed up by facts but serve as guidence.

Widgets are places things go to be displayed

Unlike macros and wikitext, a widget is usualy a place where things go to be displayed, or interacted with, think of the $view and $edit widgets.

  • This occurs even if the result is something we can interact with such as a $button or a $select, tiddlywiki renders it and stops and then lets the user interact with it.

This is effectivly true for all widgets, except actionwidgets which have a special role, once triggered.

  • They independantly modify one or more tiddlers/fields in the wiki.

The very common widget we use is the $list widget, which seems to break this rule because we nest things inside it, but this is still true, no matter how deep you nest, each widget nesting does not communicate with what included it, they go and do what they do and must complete, before the rendering is finished, then tiddlywiki renders thet next part of your tiddler.

  • Lucky for us the result of widgets is mostly placed on the screen so we can see its output and only when the rendering finishes, can we again interact with it (think of what happens with infinite loops).
  • TiddlyWikis design makes it look like one change is imediatly reflected throughout the whole wiki, which is its beauty, but to do this it needs to be very performant and guarentee it finishes. This drives what a widget is.
    • Changing only what it must, is achived using a tree like structure, only propergate changes out along the branches that the change affects.

Yes, these Create variables include $vars and even $list (on currentTiddler), variables that are only valid within them. ie once they are closed </$let> or at the end of the tiddler.

  • These can be set with literals, references (fields/tiddlers) But ALSO evaluated “functions” and “Substituted Attribute Values”.

In closing

If you take the above into account, that widgets are nested within widgets and resolved to produce output and that it needs to be fully resolved, before moving onto the next part of wikitext (Branches of the tree from here). You may see that, $wikify trys to do the whole rendering for a nominated part then use its output in your script, before it then has to render the whole wiki (or parts that changed) to display on screen, that wikify is in some ways playing with the underlying system. It renders its contents (early) then sets a variable to the result, to be used before it renders the whole wiki.

  • The fact we do not need to be aware of the above is a tribute to tiddlywiki, but sometimes we just need to know.
  • You can perhaps see that as a result, it is best avoided, as not being in the spirit of the way tiddlywiki works. Taking something from the end and using it in the middle.

note

I may edit the above for meaning in responce to others comments or review.

4 Likes

We should avoid using wikify widget as much as possible unless necessary. There exists some awkward occasions that have to use wikify widget to hack it, like macro parameters in filters:

I see this would be useful. But then it can be as simple as rewriting how you code this. Setting the result of a macro to a variable then use that variable. And doing this with evaluated “functions” and “Substituted Attribute Values” goes a long way.

  • If the macros in question are written to use a variable name, if the paramter is not provided when called, you don’t even have to pass the parameter values when you “call” the macro in a filter.
  • Custom operators do go a long way to providing alternative methods.

The hard part is identifying occasions where there is not an acceptable workaround that allows us avoid wikify. But of course such workarounds should be documented.

  • There is also a problem where everyone wants to drive logic into one filter when they are easy to achive another way such as nesting $list widgets and multiple filters.

I must admit the way macros in filters are handled are hard to locate for example under core tiddlers with the prefix $:/core/modules/filters/ there is no obviouse filter to handle macros. Perhaps via the internal process $:/core/modules/filters/unknown.js
I think this is so and I continue to research it.

[Edited] In the tiddler $:/core/modules/filters/unknown.js to detect if it is a macro all it does is determin of a “variable exists”. I expect if we had an operatror that insists it is a macro we could add additional parameter handling [macro[macroname],[parm1],[parm2],...] etc…

[Edited2] My research shows that like any other variable, a macro used in a filter is resolved before any attempt is made to parse the filter. As a result I expect a macro (javascript rather than \define or \procedure) can not be in a position to process the titles in a filter. They tend to just return a value that is treated as a title eg; [<now YYYY>] however if it can also generate a list (more research needed)

  • however using tiddlywiki terminology I belive we can call this a Selection Constructor
    not selection modifiers

The point here is even if you extend parameter handling for macros in filters they will still ONLY be Selection Constructors, that is they will not take the titles generated before them in a filter and process them, although they can return a value like 2025 or a list of titles.

  • This is where custom or coded filter operators come into their own.
  • I have not experimented by perhaps a function, or custom operator can be called that itself uses a macro call to enable a pertitle macro action.
1 Like

@pmario perhaps this reply and mine that follows could be moved to a new topic such as “Using Macros in filters”.

Just a quick note so say thank you so much @TW_Tones . I’ll need to return to your explanation after work, tonight or tomorrow, for a fully detailed and reflective read.

1 Like

I hope it helps, but I also hope if people have a deep understanding to contrubute to this visualisation, my description is contestable, as any good one should be. But I hope moving towards complete.