Proposed <% if %> shortcut syntax

EDIT: As of this response from @jeremyruston, this OP can be largely disregarded.


@rmunn

I just read this on Github (big :clap: btw). Because the GH discussions are spread over so many different threads, I thought I’d make it worse and start another one here :stuck_out_tongue_winking_eye:

To aid discussion, here’s the relevant detail from your GH post:

\define my-filter()
[all[shadows+tiddlers]tag[todo]!has[draft.of]]
\end

<$if filter=<<my-filter>> >

<$then>

<h2>Todo items</h2>

<ul>
<$list filter=<<my-filter>> >
<li><$link /></li>
</$list>
</ul>

</$then>

</$if>

You will have read about Evan Balster’s plugin. I use it a lot. As I said in another GH thread, responding to Jermolene (@jeremyruston), I prefer this proposed layout ($then and $else becoming child nodes of $if) even though that would mean a massive (seriously – huge!) amount of editing for me should the proposal land in the core. That said, I totally get Jeremy’s stance that Even’s approach is inconsistent in walking the tree looking for siblings. I also think it “looks better”.

You can hear that “however” coming, right? :wink:

The point (finally)

To make the editing job easier for me (and anyone else using Evan’s original), could you possibly see a way to support either a filter attribute or value and match attributes (as well as not)?


<$if value=<<my-var>> match="something">

<$if value={{tiddler!!field}} match="other thing">

<$if not value=<<my-var>> match="something else">

<$if value=<<my-var>> >     <!-- "truthy" -->

<$if not value=<<my-var>> >     <!-- "falsey" -->

<!-- And, while we're here...  -->

<$else-if value=<<my-var>> match="and now for something completely different">

Aside: I think we need one source of information on GH for these discussions. If it already exits, I’d appreciate the link. Thanks.

Thanks for reading! :nerd_face:

Thanks for bringing this to the non-Github audience!

I’m afraid I have very mixed feelings about it as a core addition… I would have joyfully adopted a core $if widget a couple of years ago, but since it wasn’t an option, I’ve made extensive use of Evan’s plugin in nearly every complicated view template I’ve made. If the core alternative can’t support Evan’s value, match, and not attributes (and equally crucially, $if-$else-if-$else sequences) it will absolutely break my wikis.

@etardiff I have very similar concerns. I’m not quite sure how to approach it. The moment I upgrade to 5.3.1++, the vast majority of my wiki’s UI is going to break badly. I can’t be sure if the (seemingly) endless edit-fix-save cycle is going to work simply because, each new save is going to “fix” something that might make the next cycle unworkable (because the partly fixed UI might flummox me).

Edit them “offline” in a text editor? I have so many (umm 30?) that’s not easy either.

It’s even hard to get a line on the actual feasibility of upgrading. For example, I just did a search for “<$if” in my system tiddlers…

image

which just reminded me how much I use it inside CSS tiddlers. My UI is going to get bricked! And of course, that count is 82 tiddlers using it, not the actual number of uses inside each of them.

I’m now thinking, unless @rmunn can adopt Evan’s attr space, I might have to draw a line… :cry:

1 Like

I’ve been having very similar thoughts about upgrading. :pensive: I’ve got… let’s see, 194 UI tiddlers using <$if in my largest wiki, and many of them are quite complex. I’m not sure I can justify what might be weeks to fix all that, but at the same time, I’d like to benefit from new features (and—hopefully—fixes for bugs, like this one introduced in 5.3.0).

I suppose I could try a piecemeal approach… or perhaps this could be an official plugin rather than part of the core? @rmunn

You need to raise your concerns at: Add `$if`...`$then`...`$elseif`...`$else` widget by rmunn · Pull Request #7691 · Jermolene/TiddlyWiki5 · GitHub to be sure they will be seen.

There was a reason, why Evan’s if-widgets could not be included into the core.

Edit: did update the link

Could I ask you or @CodaCoder to post on my behalf, please? I tried to sign up but can’t get anything past the first captcha to load in either Firefox or Chrome.

I don’t think there’s any great need that you sign up at GH (especially if it’s not your “thing”). @jeremyruston often states he’s happy to receive feedback and commentary here on Talk.

@rmunn Just riffin’

<$when value=<<my-var>> match="one">
  <$then>
    <<do-one-thing>>
  </$then>
  <$otherwise-when value=<<my-var>> match="two">
    <$then>
      <<do-two-thing>>
    </$then>
  </$otherwise-when>
  <$otherwise>
    <$then>   <!-- $then could be argued redundant here -->
      <<do-other-thing>>
    </$then>
  </$otherwise>
</$when>

I see value in enhanced if-then-else only if they can be nested, but I can also see if we extend this to an element that supports a “case satement”, else statements can be constructed from it, and if designed well will look and read as if-then-else when needed.

The problem with the $ or widget is what occurse within it can only be displayed (yes, buttons can change things) but the result of a widget can’t be used to set a variable, or tiddlers/field (without a trigger)

My prefered approach to start this idea would be a redefined $list widget lets call it $if with condition, then and else parameters. Where the condition is a filter, We could even insist the result equals true or false/yes or no etc…

  • This would be nestable and simple.

Then as a seperate approach a version of a $case tool with multiple conditions, for each case, one for each case, one for all cases and one for no cases.

In all of the above cases a named section similar to slot/fill, or parameter=<<section-macro>> would allow the designer multiple ways to supply the code to use when the approapriate condition is true.

:bulb: Just got a little inspiration, I may be back.

Post script:
5.3.x now has then/else operators and filter runs

Just using a procedure

\procedure if-proc(if then else)
<$list filter="[subfilter<if>] :then[<then>] :else[<else>]" emptyMessage="error" variable=result><<result>></$list>
\end
\function is-todo() [all[current]object-type[todo]]

<<if-proc "[all[current]has[fieldname]]" yes>>
<<if-proc "[function[is-todo]]" "is todo" "not is todo">>
<$macrocall $name=if-proc if="[function[is-todo]]" then="is [[todo]]" else="not is todo"/>
  • Note I am still using <$macrocall $name= in preference to <$transclude $variable= because it reads better and works.
  • The then and else values can be many things.

Here is a link to the preview wiki created by the draft PR: Add $if$then$elseif$else widget #7691

You can play with the functionality but do not use it for production – It’s not merged into the core yet

1 Like

I am looking at that wiki and see its not dissimilar to my own transclusion / slot and fill below. The child widgets are in effect named slots, with all other “cases” handled under an else-if

  • Can we nest $if widgets or is that what $else-if is for?

My question would be could we use named cases and provide their own filters and their result in the $if or $case parameters.

\procedure if-then-else(condition)
<$list filter=<<condition>> emptyMessage="""<$slot $name="else"/>""">
<$slot $name="then"/>
</$list>
\end

<$transclude $variable=if-then-else condition="[all[current]prefix[]]">
<$fill $name="then">
if true then show this
<$list filter="[tag[TableOfContents]limit[3]]">

</$list>
</$fill>
<$fill $name="else"> if false then show this</$fill>
</$transclude>

I have posted in GitHub

I think the most understandable syntax could be something similar to “case stament” but like if-else, I think the $then adds complexity. I don’t know if the use of$elseif would be better or not.

A basic example (without using $elseif) would be:

<$conditional filter="[ ... ]">
  <$if value="1"> Do the 1st thing</$if>
  <$if value="2"> Do the 1st two thing</$if>
  <$else> Do everything</$else>
</$conditional>

If we want any similar to nested functionality. It could be added a filter or something the attribute(/“shortcut”) type in the reveal widget. But it will be other point to discuss how add the functionalliy without adding mess with any possible combination of the following attributes in the snippets.

With the reveal functionality, it would be:

<$conditional filter="[ ... ]">
  <$if type="match" value="1" > Do the 1st thing</$if>
  <$if type="match" value="2"> Do the 1st two things</$if>
  <$else> Do everything</$else>
</$conditional>

But with filter attribute could behave a filter inside of filter run with :filter prefix applied to the resulted variable from the $conditional widget.

<$if filter="[match[1]]"> Do the 1st thing</$if>

The use of a filter is more versatile but it add the complexity of filters.

Just thinking.

1 Like

Just to point out, this (or any other reworded example, like switch-case) avoids all backward compatibility issues. We shouldn’t treat this as a carte blanche opportunity for additions to the core, it’s not. There is prior art to consider: Evan’s $if plugin.

2 Likes

Agreed but also recent 5.3.x improvments, we are a long way from exploring the posibilities functions, custom widgets and parameters widget all play a role here.

I don’t see how functions might “play a role here”.

Yes, my example is look-like a switch case, but it is a basic example.

I think I should have highlighted this

Then it will be easier to make mistakes, IMHO. I think adding a wrapper to the conditional statements simplify the syntax and avoid the $then.

Any condition test can make use of functions and custom operators and in some ways “cases and if” are all about conditions. I am still researching the posibilities but functions help a lot.

  • I can illustrate this later

would it break existing wikis using the plugin if <$if/> was renamed (like to <$cond/> or something) but <$then/> and <$else/> stayed the same? if the plugin only looks at then/else widgets inside of “if”, then we could keep the most obvious names for most of them and just change the parent.

to address the main point, i haven’t used the plugin as i did not know about it but simple if/else is much easier to work with than the complex reveal widget, which often needs multiple nested reveals to get the job done (and an “elseif” would add functionality the reveal widget doesn’t have, right?)

1 Like

I think what you’re proposing is what I said here. And to be clear, there is no $then in Evan’s condition plugin.

It doesn’t. The plugin supports this effective grammar:

<$if ...>

</$if><$else>

</$else>

There’s also an $else-if, but again, it’s not nested inside the $if.

Also $else can be used right after other conditionals…

1 Like

I think that the incompatibility with Evan’s Conditional Plugin means that a core <$if> widget is a non-starter. We have to a take a broad view of backwards compatibility and it is not acceptable to knowingly break a popular plugin.

I have made a PR for an alternative approach here (see Conditional Shortcut Syntax by Jermolene · Pull Request #7710 · Jermolene/TiddlyWiki5 · GitHub). Instead of using the widget syntax, it introduces a completely new shortcut syntax that is as easy to type as possible:

\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">>

There is a preview of the PR to try out here.

3 Likes