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.
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.
$list
widget + a filterIn 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.
$reveal
widgetA 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 filterSometimes 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!
Several widgets will display their content if they find no matches, eliminating the need to create a $list
or $reveal
widget at all.
$transclude
fallbacksThe $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
fallbacksThe $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.
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.
Repeat the previous exercise, but use a $reveal
widget instead of a $list
widget.
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 answerUpdate the MeetingInformationTemplate
to use a fallback to display the text (no time specified)
if there is no at
field on the tiddler.
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.