This is a stripped-down version of a single section of Grok TiddlyWiki, optimized for fast loading and readability by search engines. Some features are missing.

For the full Grok TiddlyWiki experience, please visit the wiki version of this page.

Conditional Expressions

 16th October 2024 at 7:27am

Often, we don't want to show all of the wikitext in a template on all tiddlers to which it's applied. Rather, we want to show parts of the wikitext only if some condition is true.

We can achieve this using conditional expressions (or conditionals for short). Conditional expressions are based on filters. If the filter returns at least one result, the contents of the conditional are rendered. Otherwise, nothing at all is rendered. The syntax looks like this:

<% if [<storyTiddler>match[Conditional Expressions]] %>
  The title of the current tiddler is “Conditional Expressions”.
<% endif %>

<% if [<storyTiddler>match[When Pigs Fly]] %>
  Pigs are flying – better watch out!
<% endif %>

The title of the current tiddler is “Conditional Expressions”.

The match filter operator passes through any tiddler whose title exactly matches the match step's parameter, and filters out all other tiddlers. It's indispensable in many conditional filters. The <storyTiddler> variable retrieves the name of the tiddler which is currently being shown in the story river. We have to use that in this snippet to get the expected result, rather than <currentTiddler>, because Grok TiddlyWiki snippets are their own tiddlers.

You can see that the filter in the first conditional returns a result, since the title of this tiddler is Conditional Expressions, so the contents of the conditional are rendered. The second returns no results, since the title is not When Pigs Fly, so nothing is rendered.

Notice that a conditional expression looks much like an HTML element, except there are percent signs % right inside the angle brackets, and where you might expect to see <% /if %>, you instead see <% endif %>. The spaces inside the percent signs are optional, but as with the spaces inside {{{ triple braces }}}, your wikitext will quickly become very hard to read if you omit them!

The TiddlyWiki documentation calls this the “conditional shortcut syntax,” which is a big mouthful and hard to remember. In this book, we will call a use of this pattern a conditional expression or occasionally even just a conditional.

A real example

In Templates and the Current Tiddler, we created a ContactInformationTemplate:

!! Information about {{!!title}}

* ''Email'': {{!!email}}
* ''Phone'': {{!!phone}}
* ''Family'': {{!!family}}
* ''Manager'': {{!!manager}}

This template is nice as far as it goes, but it looks rather ugly when applied to a tiddler which is missing some of the fields, such as ChrisSmith:

It would be cleaner to show each bullet point only if the field actually has a value. To achieve this, we can add a conditional expression around each one:

!! Information about {{!!title}}

<ul>
  <% if [all[current]has[email]] %>
    <li>''Email'': {{!!email}}</li>
  <% endif %>
  <% if [all[current]has[phone]] %>
    <li>''Phone'': {{!!phone}}</li>
  <% endif %>
  <% if [all[current]has[family]] %>
    <li>''Family'': {{!!family}}</li>
  <% endif %>
  <% if [all[current]has[manager]] %>
    <li>''Manager'': {{!!manager}}</li>
  <% endif %>
</ul>

The bodies of conditionals can be on one line or multiple lines, and they can contain arbitrary wikitext. Nevertheless, in this example, we needed to switch to using HTML for our list instead of wikitext syntax. The intervening conditionals would split up the bullet points into multiple lists if we used wikitext syntax, preventing them from displaying correctly (see also Block Mode and Inline Mode, in an upcoming chapter).

Nesting and else clauses

What if none of the contact fields are populated? In this case, we might want to provide a message saying that there is no contact information available, so we won't think something is wrong when we look at the template. To achieve this, we'll need to display something both if a condition is true and if it's false. We can do that by adding an <% else %> clause to the conditional, accompanied by an appropriate filter:

<% if [all[current]!has[email]!has[phone]!has[family]!has[manager]] %>

  There is no contact information available for {{!!title}}.

<% else %>

  !! Information about {{!!title}}

  <ul>
    <% if [all[current]has[email]] %>
      <li>''Email'': {{!!email}}</li>
    <% endif %>
    <% if [all[current]has[phone]] %>
      <li>''Phone'': {{!!phone}}</li>
    <% endif %>
    <% if [all[current]has[family]] %>
      <li>''Family'': {{!!family}}</li>
    <% endif %>
    <% if [all[current]has[manager]] %>
      <li>''Manager'': {{!!manager}}</li>
    <% endif %>
  </ul>

<% endif %>

Notice that we've nested the conditionals – put more conditionals inside the <% else %> clause of the outer conditional. As with HTML tags, this is perfectly valid, and even common.

One gotcha to be aware of

In many places in TiddlyWiki, when you want to use a filter, you put it in "quotation marks". No quotation marks are involved in a conditional expression, and if you inadvertently include them, the condition will always be true, no matter what the filter is:

<% if "[<storyTiddler>match[When Pigs Fly]]" %>
  Pigs are flying – perhaps you made a syntax error?
<% endif %>

Pigs are flying – perhaps you made a syntax error?

This can be quite perplexing if you've never seen it before! What's happening is that you're turning the entire filter expression into a single literal tiddler name – namely, a tiddler called [<storyTiddler>match[When Pigs Fly]]. A single tiddler name is a valid filter expression which outputs itself when evaluated, so we get a result, and the contents of the conditional are rendered.

Exercises

Exercise: (m) [Ex:LocalCalls]

You can add multiple clauses to a single conditional expression using <% elseif %>. First there must always be an <% if FILTER %>, then there can be zero or more <% elseif FILTER %>s, and finally there can optionally be an <% else %> clause. The first clause whose filter returns a result is used.

Suppose that you're in the 212 area code, and your office still uses landline phones. Within the ContactInformationTemplate, after the contact information list, show whether a call to this person will be local, long-distance, or toll-free, depending on their phone number.

You may assume that the area code is the first three characters of the phone field. Use the filter steps split[]first[3]join[] (turn each character in the input into a single tiddler name, then discard all but the first three, then join all the tiddler names into a single tiddler name) to select the first three characters of a single input tiddler.

Consider a number to be local if it's in the current area code, and to be toll-free if its area code is 800, 888, or 877. All other numbers are long-distance.

Store both the current area code and the list of toll-free area codes in tiddlers, called CurrentAreaCode and TollFreeAreaCodes, respectively, so that you can easily change these values in the future if necessary.

go to answer

Exercise: (m) [Ex:ConditionalProcedure]

This code snippet is quite repetitive:

<ul>
  <% if [all[current]has[email]] %>
    <li>''Email'': {{!!email}}</li>
  <% endif %>
  <% if [all[current]has[phone]] %>
    <li>''Phone'': {{!!phone}}</li>
  <% endif %>
  <% if [all[current]has[family]] %>
    <li>''Family'': {{!!family}}</li>
  <% endif %>
  <% if [all[current]has[manager]] %>
    <li>''Manager'': {{!!manager}}</li>
  <% endif %>
</ul>

Write a procedure that wraps the logic that's repeated here, and call it four times to produce the same result.

Hint: To transclude a field of the current tiddler whose name is in a variable, use the $transclude widget with the $field parameter: <$transclude $field=<<myvariable>>/>.

go to answer

Exercise: (m) [Ex:ConditionalProcedureContinued]

The result of Ex:ConditionalProcedure is still repetitive in that it uses the same procedure call four times in a row, with only the field name changing. Can you remove even this repetition, so there is only a single procedure call?

Hint 1: What TiddlyWiki feature have we seen that renders some wikitext multiple times?

Hint 2: A type of filter expression we haven't discussed explicitly yet consists of a tiddler list (sequence of tiddler names).

go to answer

Takeaways

Takeaways are not available in the static version of Grok TiddlyWiki. Visit the wiki version of this page to study takeaways.

↑ 4: Transclusion