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.

Hiding and Showing Things

18th April 2021 at 11:55am

Oftentimes you want to show content only in certain circumstances (programmers might say an if-statement or conditional is required). There are a number of ways we can accomplish this. In many cases, you'll have your choice of several methods, but some are more effective or readable than others in individual situations.

The $list widget + a filter

In several earlier examples and exercises, we've seen that the $list widget can be used to accomplish this, but let's review how that works, as it's a versatile but unintuitive technique.

The contents of a $list widget are rendered once for each element in its associated filter. If we can ensure that the filter we use returns either one or zero output tiddlers, we can use it to control showing or hiding some content.

Let's suppose we'd like to display a transclusion of the template ProjectTableOfContents at the bottom of all project tiddlers, but only if the tiddler $:/config/ShowProjectTocs is set to yes. We might start with placing this on a tiddler tagged with $:/tags/ViewTemplate:

<ul>
<$list filter="[{$:/config/ShowProjectTocs}match[yes]]">
    <$list filter="[all[current]tag[Project]]">
        {{||ProjectTableOfContents}}
    </$list>
</$list>
</ul>

There's a big problem with this snippet, though, which you'll notice if you create a ProjectTableOfContents template and try it in your wiki: the current tiddler is messed up by the outer $list widget, so the inner $list widget never finds anything (unless you happen to have a tiddler called yes tagged Project, in which case it will always display the template with the content appropriate to the yes tiddler!). Fortunately, there's an easy fix: add variable=_ to the outer widget, so that it doesn't alter the currentTiddler variable. (_ is a concise, easy-to-type variable name that is commonly understood to mean you don't care about and are not using the value, but TiddlyWiki doesn't care what you name it – you could just as easily call the variable trash or not-used or idontcare if you prefer.)

Here's an improved version:

<ul>
<$list filter="[{$:/config/ShowProjectTocs}match[yes]]" variable=_>
    <$list filter="[all[current]tag[Project]]">
        {{||ProjectTableOfContents}}
    </$list>
</$list>
</ul>

If you're not comparing against a single tiddler, whether the current tiddler or a hard-coded one like $:/config/ShowProjectTocs, you won't be able to guarantee that there is only one match. In this case, you need to use the first[] operator to avoid having the contents of the widget unexpectedly repeat a bunch of times. For instance, you might want to know if any tiddlers in the wiki have been modified in the last N days (using the days operator). You might try something like this:

<$set name=numDays value="-500">
<$list filter="[days<numDays>]" emptyMessage="Nope.">
    Yep.
</$list>
</$set>

Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep. Yep.

That didn't work so well! Try adding the first[] operator to the snippet to correct it.

Also notice the use of the emptyMessage attribute to the $list widget above. This text is displayed if there are 0 results for the filter, and thereby saves us from having to create a second $list widget with the opposite condition. If you want to include a large amount of text in the empty condition, you can place it in a macro and call the macro as the value of this attribute.

The $reveal widget

A method we haven't seen yet is the $reveal widget. Rather than using a filter, this widget includes content based on whether a specific field matches a specific value. Thus, it's somewhat less powerful but often more convenient. Here's the basic syntax:

<$checkbox field="showtest" checked="yes" unchecked="no"> Show the text</$checkbox>

<$reveal state="!!showtest" type="match" text="yes">
    Here is the text!
</$reveal>

In addition to match, as shown above, type can be set to nomatch to invert the match (match and nomatch widgets are often used in pairs to show one thing if something is true and another if it's not). There are also options to allow the widget to be used to compare numeric values (e.g., only show if a field value is greater than 5); check up the documentation for details.

The $reveal widget has one major limitation worth noting: unlike the $list widget, it creates a new div or span HTML element to wrap the revealed content in. This means you can end up with corrupted output if you use it in certain contexts where one of those elements doesn't belong, for example inside a table (notice the column header is the wrong width when expanded):

<$checkbox field="showtest" checked="yes" unchecked="no"> Show an extra column</$checkbox>
<table>
<tr>
    <th>Column 1</th>
    <$reveal state="!!showtest" type="match" text="yes">
    <th>Extra column</th>
    </$reveal>
    <th>Column 2</th>
</tr>
<tr>
    <td>Data 1</td>
    <$reveal state="!!showtest" type="match" text="yes">
    <td>Magic extra data</td>
    </$reveal>
    <td>Data 2</td>
</tr>
</table>

Column 1 Column 2
Data 1 Data 2

$set with a filter

Sometimes you don't need to include entirely different content in a tiddler depending on a condition, you just need to set a variable to a different value. Adding filter and emptyValue parameters to the $set widget allows you to set the value of a variable to one of two values, the normal value if the filter has more than 0 results, and emptyValue if it has 0:

Your name: <$edit-text tiddler="$:/temp/ExampleNameField" tag="input" default="" />

<$set name="username" filter="[[$:/temp/ExampleNameField]get[text]]" value={{$:/temp/ExampleNameField}} emptyValue="Nobody">
    Hi <<username>>!
</$set>

Your name:

Hi Nobody!

Fallbacks

Several widgets will display their content if they find no matches, eliminating the need to create a $list or $reveal widget at all.

$transclude fallbacks

The $transclude widget is the long syntax for transcluding a field of a tiddler. The tiddler name is optional; if not provided it defaults to the current tiddler.

<$transclude tiddler=<<currentTiddler>> field="description"/>

-----

<$transclude field="description"/>

-----

{{!!description}}

This is a nice wikitext snippet.


This is a nice wikitext snippet.


This is a nice wikitext snippet.

In addition to its ability to override whether parsing occurs in block or inline mode, as discussed in Block Mode and Inline Mode, you can use the content of a $transclude widget as a fallback if the field doesn't exist.

<$transclude field="nonexistentfield">
  The nonexistent field does not exist.
</$transclude>

The nonexistent field does not exist.

(Be aware that the $transclude widget does not change the current tiddler – in other words, it treats the transcluded tiddler as a template for the current tiddler. If you want to get the equivalent of a straight {{transclusion}}, you need to wrap it in a $tiddler widget, as described in Miscellaneous Widgets.)

$view fallbacks

The $view widget is much like the $transclude widget but displays the field contents in different formats, like dates or URL-encoded text, rather than wikifying them. It supports fallbacks exactly the same way as $transclude does:

<$button set="!!adate" setTo={{!!created}}>Show Created Date</$button>
<$button set="!!adate" setTo="">Hide Created Date</$button>

<$view field="adate" format="date" template="This tiddler was created on MMM DD, YYYY.">
    The date is not currently set.
</$view>

The date is not currently set.

Exercises

Exercise: (m) [Ex:ViewTemplateExplicitHide]

Change the ViewTemplate tiddler that displays the contact information template so that it does not display if the hide-contactinfo field on the contact tiddler has the value yes. Use a $list widget.

go to answer

Exercise: (m) [Ex:ViewTemplateExplicitHideReveal]

Repeat the previous exercise, but use a $reveal widget instead of a $list widget.

go to answer

Exercise: (m) [Ex:BacklinksConditionalDisplay]

Update your template that displays a list of links and backlinks so that the list doesn't appear if there are no links or backlinks.

go to answer

Exercise: (m) [Ex:EmptyAtField]

Update the MeetingInformationTemplate to use a fallback to display the text (no time specified) if there is no at field on the tiddler.

go to answer

Exercise: (m) [Ex:ConditionalSetAt]

Repeat the previous exercise, but use a conditional $set widget. It's OK if the behavior when the at field is empty, rather than missing, differs from the previous exercise.

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.

↑ 7: Tips and Tricks