Proposed <% if %> shortcut syntax

As I wrote in GitHub, I believe If/then/else widgets developed by Robin follow the same philosophy and syntax of TiddlyWiki widgets! So, why not use Robin implementation?

It is not a good reason to stop a core feature development because there is a rather old plugin. We should always stick to the core and core backward compatibility as TW development policy!

We know some of good Tobias Beer codes/plugins are now part of the core.

Also the Evan condition widget is developed based on older concept. and is similar to $reveal.

I myself always stick to TiddlyWiki core features and when I can use a core feature, I use it, not third party one. So, I am highly in favor of Robin development.

See Robin latest efforts here:

1 Like

Would you give an example from TiddlyWiki scripting syntax using something like not?

TiddlyWiki uses ! for not , e.g. [tag[Test]] and not [!tag[Test]].

This is not a TW compatible syntax: <$if not value={{$:/StoryList}}>.

Have you tried Robin development of $if widget? Please take a look. It is here https://tiddlywiki5-r79sfdnqv-jermolene.vercel.app/ with full documentation and examples. It is clear, concise and very easy to learn, as it follows closely the TiddlyWiki widgets syntax.

Your fear may go away or you may find solution to convert your code using core feature if for any reason you have to upgrade to TW 5.3.2+.

<!-- if my-var contains 0, "", [empty list] or blank... i.e. "falsy" -->
<$if not value=<<my-var>>>
  <do-something>>
</$if>

That’s filter syntax.

In wikitext HTML, not is being treated as an HTML boolean attribute like, for example, readonly in regular HTML.

What do you mean? The syntax perfectly is fine. Although, checking the (negated) value of the $Storylist text field is always false (in a normal Tiddlywiki, anyway). This might be more useful:

<!-- if story is empty, display something cool... -->
<$if not value={{$:/StoryList!!list}}>
  <display-cool-stuff>>
</$if>

It’s not that I find Robin’s approach logistically complicated or difficult to use - as I said, I would have been very happy to use it instead of Evan’s plugin if it had been available a couple of years ago. It’s just that, since it was not available back then, I’ve already incorporated Evan’s $if widget in hundreds of places across hundreds of template tiddlers (and multiple wikis), and having to convert all that just so that my wikis would function the same way they do now would be a major barrier to my adoption of future TW versions.

I know that it’s possible to accomplish similar effects with $list (which I also often use - often in conjunction with Evan’s $else). $reveal feels verbose and clumsy by comparison; I’ve avoided it since I first discovered Evan’s plugin as a concise alternative.

Indeed. The semantics are wrong (for this purpose). Were they not, @jeremyruston would not be considering any proposals for improvement in this area.

That is right! $list can be used instead of $reveal. I think Evan’s $if somehow tried to address users need for several clumsy $reveal widgets.

I myself always used $list for decision making and rarely $reveal. Filters allow to make decision based on simply or complex filters. I used this methodology for if/then/else-if/else in TiddlyWiki. Note that condition can be a simple or complex several steps/runs filter.

<$list filter="[<cond...>then[true]else[false]]" variable=something>
  <$list filter="[<something>match[true]]"> 
       TRUE BLOCK
  </$list>
  <$list filter="[<something>match[false]]"> 
       FALSE BLOCK
  </$list>
</$list>

You may use shorten structure when you need only a simple if construct, or you need simple else (here you use can emptyMessage with attribute). The whole structure can be wrapped in a macro so prevent you from extra typing! Or you may use macros for false/true parts and just type one $list with emptyMessage if you need if/then/else.

Yes, and most decision making in TW is based on filters. Widgets and Filter are the heart of TiddlyWiki.

That is another thing! They are used normally for on/off state like disabled/required. They are not used for conditional statement. Here we are talking about if/then/else construct, so we need to write conditional statements. In TW these statements are filters. The $reveal is an exception, which most user with the current state of TW avoid using it where possible.

I mean this syntax which is used in Evan’s plugin is not a TiddlyWiki compatible syntax.

Look at this example from Formulas for TiddlyWiki — spreadsheet-inspired number crunching (chronicles.wiki)

<$if      value={{!!animal}} match=cat>  Meow!  </$if>
<$else-if value={{!!animal}} match=dog>  Bark!  </$else-if>
<$else-if value={{!!animal}} match=bird> Tweet! </$else-if>
<$else> This isn't like any animal you've seen before. </$else>

This is very confusing! the <$else-if> is a separate widget it is not inside the first $if, but it is part of that $if widget.

Add a line break between them

<$if      value={{!!animal}} match=cat>  Meow!  </$if>
 <$else-if value={{!!animal}} match=dog>  Bark!  </$else-if>
 <$else-if value={{!!animal}} match=bird> Tweet! </$else-if>

<$else> This isn't like any animal you've seen before. </$else>

It returns error. Why?

How do you teach this syntax to new learners?

I think TiddlyWiki in 5.3.1 is very powerful in comparison to TW 5.1.x (where condition plugin is developed). It worth to have its own simple to follow if construct. Many users prefer to use core features. There no need to always update to latest TW, so TW with condition plugin can work as before and we can support Robin efforts for $if in core.

1 Like

This is not my reason for objecting to a core if widget, it is because although useful I think we can design a more comprehensive solution. To maintain backwards compatibility putting a widget in the core is adopting it as proposed indefinitely. I do appreciate @rmunn’s efforts, and I think Robin raises this to an importance level it deserves; However I think it needs more and longer development times nif we are to put an $if in the core and documentation, especially since the release of 5.3.x offers so many possibilities. For example here is my custom widget for if then else with an example;

This works now

\widget $if.then()
<$parameters filter="[all[current]]" $params=all-params>
<$list filter=<<filter>> variable=slot>
   <$slot $name=<<slot>>/>
</$list>
</$parameters>
\end $if. Then


<$if.then filter="[all[current]has[switch]then[then]] ~[[else]]">
   <$fill $name=then>then result</$fill>
   <$fill $name=else>else result</$fill>
</$if.then>
  • It is an idea like one we @Mohammad shared back in the day with calling named macros.
  • In the above you define the then and else code in fill widgets

But using this approach it can be simplified to a case statement

This works now

\widget $if.case()
<$parameters filter="[all[current]get[case[]]" $params=all-params>
<$list filter=<<filter>> variable=slot>
   <$slot $name=<<slot>>/>
</$list>
</$parameters>
\end $if.case
  • Just set the filter result so the condition results in a named case with a matching fill widget when calling.

Offline I have not only written code that uses the fill widgets but conditionally

  • calls a procedure,
  • a widget
  • and transude tiddler content.
  • I also forsee a widget which can use the contents of arbitrary html tags to find the content for each condition.

the $if widget does not propose a way to do this versatile set of conditional outcomes but proscribes a particular way and set of outcomes. This is too restricted in my view to use a valuable widget name $if.

I am yet to test @jeremyruston’s approach but to me this avoids the compromises of adding a core widget and has little impact elsewhere. I hazard a guess we can use it to also call procedures, use fill/slots, transclude etc… as well.

@jeremyruston My only questions so far would be;

  • Can we choose if the result is inline or block modes?
    • Ideally without introducing first blank lines
  • Can we use the result as a value to an attribute?
    • With or without wikification
  • Could we make this valid within wikitext not just procedures?

I love this community.

2 Likes

The new parser options Jeremy proposed in draft PR 7710 internally creates list widgets. They can be tested with the draft preview Edition.

If you switch the edit-preview to “parse-tree” or “widget-tree” you can see what’s created internally

Click to show the image

Code

\whitespace trim
\define animal() ElephantX
{% if [<animal>match[Elephant]] %}
    It is an elephant
{% else %}
    It is unknown
{% endif %}

The advantage is, that the existing list-widget can be reused and the refresh mechanism is highly optimized already.

The disadvantage is, that it introduces a completely new syntax {% if %} wich is very similar to existing templating engines Jinja or NunJucks.

I do not know if that’s a coincidence or if ideas are borrowed from them.

Hi Tony
Thank you for your input, specially the custom widget for if/then/else.
I follow your other threads on development of custom widgets using TW 5.3.1. They are really helpful and speed up onboarding with 5.3.1

Like you for if/then/else I think we should consider new features in 5.3.1.

My only concern is consistency and logical adherence of all parts of TW scripting.

1 Like

:confused:

Please. I know what we’re talking about here – I opened the thread. The point of the thread, which I opened in Developers, is to ask a developer of a proposal to make my (and others) editing job easier should the proposal come to fruition.

What this thread ISN’T about is debating the merits of any given plugin – especially when a particular plugin is earmarked for obsoletion, if not flat-out removal. It’s completely fine if you don’t like it. You’re welcome to hold your own opinion, however right or wrong you may be – it’s not a matter of debate here. What this thread IS about is the position some of us find ourselves in because of decisions we made in good faith, years ago and asking that our task moving forward might be eased by making some changes to said proposal. ← There’s no debating that at all – we are where we are, sadly.

You’re not in that position. Good for you. If you have an answer to the problem intimated in the OP, I would be glad to hear it.

1 Like

And, by definition, avoids disturbing the past!

Thanks, @pmario (and @jeremyruston )

Hi @CodaCoder,
Thank you for your clear points. What I wrote is my technical point of view. Absolutely there is no debate.
The good news is every user can live with existing features. When a new feature is introduced, TiddlyWiki does not force to use it, because all old features, functionality are still there. So, all people with all types of opinions can still use TiddlyWiki.

Thank you @PMario

I understand (and greatly appreciate!) that this is the general design principle behind TW, but it isn’t always the case - that’s why @CodaCoder opened the thread. If future versions of the core do implement a new widget with the same name as the one defined in the plugin we’re using and it doesn’t function the same way, we will by definition be losing functionality we have at the moment.

I think you implied earlier in the thread that we don’t need to upgrade affected wikis past 5.3.1… and while that is technically true, one of the reasons I’d really like to be able to keep up with new releases is because a bug introduced in 5.3.0 did remove a previous functionality I’d already built into my wiki. I’m optimistic that this will be addressed eventually: Jeremy and our other contributing developers have always been very committed to fixing bugs. But if I have to stick with 5.3.1 indefinitely, I’ll lose access to future fixes as well as future improvements.

If @rmunn 's widget were being proposed as an official plugin (alongside staples like CodeMirror and the menubar) rather than a core feature, I’d be very happy with it in its current state!

:dart:

And the link @pmario suggested: Jeremy’s PR also allows older, working code to survive:

\procedure test(animal)
{% if [<animal>match[Elephant]] %}
  It is an elephant
{% else %}
  {% if [<animal>match[Giraffe]] %}
    It is a giraffe
  {% else %}
    It is completely unknown
  {% endif %}
{% endif %}
\end

<<test "Giraffe">>

<<test "Elephant">>

<<test "Antelope">>

:+1:

Disclaimer: I have never used Evan Balster’s plugin, so I may stance nonsense here. If so, please tell me.

First let me say I really crave for a <$if> widget, and I think it’s such a basic building block that it should belong in the core.

Next I don’t think adding a new syntax as per @jeremyruston’s PR is the right thing to do, as TW already provides a perfect syntax for this: widgets. It’s even what this threat is all about: the <$if> widget is so obviously the right solution that several people used it in incompatible ways.

Also there’s a large code base already using Evan Balster’s plugin, and merging @rmunn’s work in the core would break this code base.

So, how could we make both Evan Balster’s plugin and @rmunn’s work cohabit?

A proposed solution could be to provide:

  • a new version of Evan Balster’s plugin renaming its widgets to something else (let’s say <$eb.if>, <$eb.else>, …
  • and also a migration tool that could transform every <$if> to the new widget name, something along the lines of @Mohammad’s Commander.

No new features, just a widget renaming and a code transformation tool.

My 2 cents,

Fred

3 Likes

Some latteral thinking here but I would emphasis the 5.3.x improvments offer other lateral and innovative ways to handle this. For example it should be quite easy to redefine evans if to a new name, or the opposite, redefine a core $if to another name leaving evans to dominate if already in use. With custom and installable widgets.

  • Although I am arguing that we should consider an $if widgets, or by another name BUT develop a more mature solution to justify the adoption of an $if widget, especialy if it clashes with the only effective version that has being available for a long time, in evans plugin. Future backwards compatibility means we should be careful here.

You can see here Further use of $params with $parameters widget a detailed discussion on aspects of the 5.3.x features to pass an arbitary number of parameters from one widget or procedure to another. Just what we need to redefine a widget.

I can forsee an option to choose ones $if widget “provider”.

1 Like