[v5.3.2-pre] Peeking at the Conditional Shortcut Syntax

Folks, The 5.3.2 Prerelease now has a number of new features listed and one of these is quite different in form and possibly ease of use, that is the Conditional Shortcut Syntax.

  • I have started this Topic to solicit initial observations and to encorage our broader community to have a look before these become part of the next version of tiddlywiki.
  • Unless you are interested in a preview I suggest you ignore this for now and the users that do will help you come to terms with the new features once they understand themself.

For the inquisitive, please read on.

  • When the pre-release becomes the next version we are bound to maintain backward compatibility, so its great to get it right in the first instance.
  • If you have the time and an interest perhaps you can pick another change in the next release and start another topic.
  • It is really helpful that users of different skills have a look and give us your impressions and experts a like to push the boundaries of new features.
  • What you share now will also help development of the documentation.

For example this is documented here and the leading example is;

<% if [<animal>match[Elephant]] %>
  It is an elephant
<% elseif [<animal>match[Giraffe]] %>
	It is a giraffe
<% else %>
	It is completely unknown
<% endif %>
  • This is the first example of “naked filters”
  • Only if and elseif are provided filters.
  • They can be nested.

I took another example and moved the condition into a function demonstrating how when using functions we can make this into a plain language form.

\function .host-local-file() [{$:/info/url/protocol}match[file:]]

<% if [.host-local-file[]] %>
  Loaded from a file URI
<% else %>
  Not loaded from a file URI
<% endif %>
  • Note here I am abandoning the filter for a function, that returns something or not
  • I have tested the use of <<local-tiddlywiki>> and that also works.

Some thoughts and Questions as I start exploring this;

  • Since this is Wiki text it should be valid in macros and Procedures, transclusions, fieldnames, and inside widgets, now even custom widgets.
    • What impact could this have on the way we represent conditional statements?
    • What are its strengths and weaknesses when compared to filters in other widgets such as the list widget?
  • In other languages that provide if then else structures, are their any features you would like here?
  • This almost looks like pseudo code, what other features could we have that support a complete set of pseudo code elements that represent actual code?
  • Perhaps this will prove to be an elegat way to document filter examples and syntax?
  • Since we can use “naked filters” how can we craft meaning full filters eg [all[current]object-type[notes]]
    • Perhaps we need a shortcut for current tiddler?
    • eg \function this() [all[current]] and use this[] to set the current tiddler.
      • What other names or symbols could we use?
      • I favor one I have used before the tilde, which tends to mean the root word in dictionaries here it means the current title/tiddler
        • eg \function ~() [all[current]] so [~[]... is equivalent to [all[current]... or [<currentTiddler>...

Usage guidelines

  • Perhaps there is an argument to use this approach when you just want the result of the filter to choose what to display, but not to use any value it creates?
    • Although you can use the filter again eg {{{ filter }}}
  • We often use the list widget as a condition but often we also use it to list multiple items, There is an argument that the if/(then)/else/endif is when we are not acting on a list “unless it is inside a list”.

Technical Questions;

  • Would there be a way for us to reference the result of the filter to use in the content?
  • Is there a way to use filters with multiple runs in them (Yes via a function?) but how abount inline.

Notes as I continue to research the new Conditional Shortcut Syntax;

You can place this inside a procedure (and elsewhere)

  • However like macros and procedures it will only be rendered at the last moment.
  • Although not recomented you can wikify a macro or procedure to set the output to a variable.

You can remove additional spaces, except before the filter;

<%if [{$:/info/url/protocol}match[file:]]%>
  Loaded from a file URI
  Not loaded from a file URI

Or even

<%if [{$:/info/url/protocol}match[file:]]%>Loaded from a file URI<%else%>Not loaded from a file URI<%endif%>
  • But then you loose the value of the readability.

We often want one thing to unfold after another, like a series of questions.

  • If the if/then or else contains the right filter and the meanes to change a value in a filter we can move from one step to another.
    • For example this has two questions, but only asks the second once the first is answered.
\function store() [{$:/status/UserName}addprefix[$:/answers/]]
\function ~() [all[current]]

<%if [<store>!has[Q1]] %>
Question 1?
<$button setTitle=<<store>> setField=Q1 setTo=A1>A1</$button>
<$button setTitle=<<store>> setField=Q1 setTo=A2>A2</$button>
<%elseif [<store>!has[Q2]] %>
Question 2?
<$button setTitle=<<store>> setField=Q2 setTo=A1>A1</$button>
<$button setTitle=<<store>> setField=Q2 setTo=A2>A2</$button>
  • This can go arbitarily deep
  • More complex conditions could unfold some questions only if another was wrongly answered.
  • This could be usde to allow a step wise process only procedding under the right conditions.

I continue the journey :nerd_face:

Hi TW_Tones - did you post the link you intended to? I am new to this theme and indeed looking forward to the conditional shortcut syntax but the connection to the link posted wasn’t obvious to me.

Thanks, Fixed, and I have no idea how that happened.

Wait what?

Why not just have an <$else> widget? Why are we introducing all of this new syntax for something only power users will ever use?

<$list filter="[<store>!has[Q1]]">

This is way simpler. It adds less, and it would better address usage for <$list> and <$reveal>.

And if someone is making a chain of if-else statements, they’re not using Tiddlywiki the way it should be used. It’s about templates, not imperative programming.

This syntax is already supported by Evan Balster’s Condition plugin—which was part of the problem. The initial proposal for a core if/else defined an <$if> widget with <$then> <$elseif> <$else> widgets nested inside it—but to my understanding, it would not have supported <$else> following a <$list> or <$reveal> (nor would it have supported non-nested <$if></$if><$else></$else> sequences). As @CodaCoder observed, this would have been a breaking change for those of us already using Evan’s plugin, which has been around since 2017.

The new conditional syntax was thus a compromise to protect backwards compatibility. I agree that it’s visually clumsy, but I’m glad to have it, as it means I can happily ignore it and continue using <$else> as I have for years.

I’m not entirely sure I follow here. As (I suppose) a power user, I actually find myself using if-else if-else chains all the time in my templates—most frequently to determine which subtemplate should be used.

Sorry for the digression, @TW_Tones! I’m happy for you to become the local <% if %> expert. :slight_smile:

If there’s already a plugin that does all this, I would say it should remain as a plugin. These features aren’t “must-haves”.

You are a power user. So am I. It’s not a problem for us to download a plugin if it’s important for our current project. I do spend most of my time on Tiddlywiki making plugins (or updating plugins for the endless stream of new features that keep getting added). I can’t use these new syntaxes because a lot of users of my plugins froze their Tiddlywikis at older versions. Nor do I need to use these features, because they are just syntactic sugar. They don’t actually provide solutions to previously unsolvable problems.

I say it’s not the way TiddlyWiki is supposed to be used because TiddlyWiki is designed for modularity, not conditional logic. So functionality is introduced through modules which get plugged in. Or tiddlers with tags that get looped in implicitly through filters. Tiddlers are intended to be small, almost atomic, and to be looped in declaratively. That’s why there was a big move away from data-tiddlers (or at least that’s what I thought.).

Big chains of if-elses inside of a single tiddler is often a sign that a refactoring may be called for. I might not always be right, but in the odd cases where I’m wrong, I don’t know if it’s worth having an entire syntax dedicated to supporting a TiddlyWiki anti-pattern.

Thats to be seen, here I want us to learn it, support it and/or criticism of it.

This and other options were considered and debated.

To me this is so fundimental it should be core behaviour.

An initial look into the new format is it will be a good complement to list and reveal which are currently our main conditional content tools.

But I do feel the same about leveraging the existing contructs.

Plus :cascade, it could be argued.

Please check your second “function” code example in the OP. It does not work.

I think it’s very confusing to overload the tilde ~ sign with a user defined variable, since tilde is already used in filters for :else filter run.

See: https://tiddlywiki.com/#Filter%20Expression

I fixed the filter, just had the wrong name. A copy paste error.

  • I’m not too worried as it’s a macro not a filter run prefix and tend to use else for readability now.
  • However If you have a better name that is really short and can be entered from the keyboard please let me know.
  • It is meaningful as I suggested and could shorten 50% of my filters.

Would you object to [*[]... it also look like current.

IMO the TW core is a good example that single-character shortcuts are problematic over the long run. We do run out of usable meaningful characters, that are available on different language specific keyboard layouts.

IMO if you really need a shortcut for currentTiddler then use cT. – But also here, the experience shows, that verbosity has an advantage.

I think that’s the best argument for verbosity.

From my point of view we should let ~ and _alone for variable names, if we want to establish best practices. Tilde and underscore are not good enough


Was that a bad question of mine?, You dont object?, I will assume you do object :nerd_face:

Sorry English is not my main language and consulting leo.org did give me the wrong impression.

I think verbosity wins in the long run, even if it is more to type.

Don’t be, I used a troublesome “turn of phrase”.

They are also wrong in official docs. I’ll create a PR to fix them.

Just some pointers to more context. There has been a lot of discussions about the new syntax here and at GitHub.

An if-then-else wikitext syntax has often been requested by standard users, since they consider nested $reveal and $list constructions unintuitive and complex.

The problem with <$list></$list> <$else></$else> format are discussed in details at GitHub. Starting with an initial PR, which was incompatible with Evan Blaster’s “condition” plugin. So it was rejected. Evan Blasters “condition” plugin is brittle, that’s why if-then-else was implemented in the way as it is now.

The merged implementation ist at: https://github.com/Jermolene/TiddlyWiki5/pull/7710

There is also a long thread about the proposed syntax from end of August 2023 here at Talk

Based on what? Your opinion? That is not reflected at all in my experience.

I suspect part of the issue may be that the $else widget will fail if separated from the closing tag of its antecedent by, say, an extra line break. I don’t mind this too much myself, especially because it does inform me when it fails (as opposed to most core widgets, which often just fail silently if their syntax is incorrect, and perhaps break something else further down the page.) But I suppose it could create some “unexpected” errors, since core widgets are generally fairly apathetic to whitespace.