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.
Filters and transclusions interact in two useful ways:
As we know, we can transclude the text
field of a tiddler by placing its title in {{double curly braces}}
. We can transclude the result of a filter expression by placing it in {{{triple curly braces}}}
; this is sometimes called a filtered transclusion. Here's a filtered transclusion of the names of the alphabetically first five sections in this book:
{{{ [all[shadows+tiddlers]tag[Section]first[5]] }}}
(The all[tiddlers+shadows]
step is required here and in many live examples to come because of the way Grok TiddlyWiki is packaged; in your own wiki, you wouldn't need this step. If you're too curious to wait for the explanation, jump ahead to Shadow Tiddlers.)
The spaces directly inside the curly braces are not required, but they're highly recommended: if you leave them out, there are so many brackets next to each other that it is nearly impossible to tell whether you've inserted the right number of them.
Let's open up the MeetingList
tiddler in our example wiki and create a list of meetings using a similar filter:
{{{ [tag[Meeting]] }}}
You'll want to put a blank line above and below this line – otherwise, all the titles will be run together (this is the block-versus-inline-mode thing again).
This is a really quick-and-dirty way of creating a list which can come in handy occasionally, but this syntax is most commonly used when we want to use a filter to create or manipulate some text and include it somewhere, either directly in the body of a tiddler or as an attribute of a widget or HTML tag. For instance, suppose we want to display a count of how many meetings we currently have notes on:
There are {{{ [tag[Meeting]count[]] }}} meetings in this wiki.
If you tweak the filter in your wiki to match this, you'll notice something a little odd, though – supposing your wiki currently has 2 meetings, 2 is a link, to a nonexistent tiddler called 2
. What's up with that?
Well, since filters are mostly designed to work with tiddler titles, when you get the output of a filter, TiddlyWiki assumes each item in the output is a tiddler, so it tries to be helpful and link it. Certain filter operators, however – like count[]
, or get[]
– will break this assumption. Fortunately, if you're fussy about having pointless links show up, overriding the default is easy – we simply use the $text
widget, which tells TiddlyWiki that we want something to be treated as plain text rather than wikitext:
There are <$text text={{{ [tag[Meeting]count[]] }}} /> meetings in this wiki.
The dynamic lists we've created so far are nice, but they've had a significant limitation: no part of the filter can change unless we go in and edit it. Often, we might like to be able to make part of the filter a value that changes, like a field or a variable.
Let's think back to the exercise where we included Jane's manager's phone number in the JaneDoe
tiddler (we've since moved this bit onto the ContactInformationTemplate
). Suppose that instead of the phone number of the person's manager, we want to list the names and phone numbers of all people listed in the family
field.
At first, this seems pretty straightforward:
<ul>
<$list filter="some filter">
<li>{{!!title}}: {{!!phone}}</li>
</$list>
</ul>
But what do we put as the filter to retrieve the contents of the family
field? We can't directly name the tiddler we want to retrieve the field from (e.g., JaneDoe
), since this snippet would then only work in Jane's tiddler. Instead, we need to refer to a value on the current tiddler somehow. Our first thought might be to define a macro, like we did in the manager exercise:
\define myfilt(people)
[enlist[$people$]]
\end
The enlist
filter operator takes a list field, with values separated by spaces or wrapped in [[double square brackets]]
, and splits it apart into individual tiddler names. If we left enlist
out, then we'd be looking for a tiddler called JohnDoe EmilyDoe
(the exact text that's in the family
field of the JaneDoe
tiddler), instead of the two tiddlers JohnDoe
and EmilyDoe
(what we meant).
OK, now let's just pass the results of calling that macro to the $list
widget:
<$list filter=<<myfilt ...>> >
Wait a sec…how do we call myfilt
with the value of the family
field? <<myfilt {{!!family}}>>
sounds nice, but isn't valid. We have to use a $macrocall
widget to pass transclusions as parameters to a macro. But sadly, this isn't valid syntax either:
<$list filter=<$macrocall $name="myfilt" people={{!!family}}/>>
You can't put a widget inside an attribute of another widget. We could turn the result of the macro call into a variable that we could pass to the filter
attribute of the $list
widget:
<$set name=filtersnippet value=...
…Wait, same problem! Dang it!
There is in fact a way to solve this problem with macros; we'll learn how to do it in Using Variables in Macros. But it should be clear that using a macro here is a whole lot more work than we want to deal with. All we really want is to pass the contents of the family
field into the enlist
operator.
Here's the syntax that allows us to do that.
<ul>
<$list filter="[enlist{!!family}]">
<li>{{!!title}}: {{!!phone}}</li>
</$list>
</ul>
Notice that there is only one set of curly braces in the filter expression, rather than two, just like there is only one set of square brackets in their place if you're providing a value that doesn't change.
If the value we wanted to use was in a variable rather than a tiddler field, we could use single angle brackets:
<ul>
<$set name="familyfield" value={{!!family}}>
<$list filter="[enlist<familyfield>]">
<li>{{!!title}}: {{!!phone}}</li>
</$list>
</$set>
</ul>
Curly braces or angle brackets can be used by themselves, not preceded by an operator, to directly introduce an arbitrary value into the filter pipeline. This is the equivalent of specifying a literal title with square brackets:
{{{ [[abc]addsuffix[def]] }}}
<$set name="myVariable" value="abc">
{{{ [<myVariable>addsuffix[def]] }}}
</$set>
Lastly, you can also transclude the result of macro calls with constant parameters into a filter:
\define partial-name(suffix) Tiddler $suffix$
{{{ [<partial-name "Forty-Two">] }}}
Sometimes a filter parameter that is transcluded into the filter with {braces}
or <angle brackets>
is called a soft parameter, in contrast to an unchanging hard parameter specified with [square brackets]
.
Actually, there's an even easier if not immediately intuitive way to make the family list, and this would likely be what you'd want to do in a real-world situation:
<ul>
<$list filter={{!!family}}>
<li>{{!!title}}: {{!!phone}}</li>
</$list>
</ul>
That may look weird right now, but when we get to Multi-Run Filters, you'll understand why this works. For now, this is more a curiosity than anything else; it certainly won't work in all situations in which you might want to substitute a field or variable value into a filter, so what we learned above is still important.
Create a list of all tiddlers that contain the title of the wiki.
$:/SiteTitle
.search
filter operator is used to find tiddlers that contain some arbitrary text.Edit the ContactInformationTemplate
so that a contact's family members each get their own bullet point, nested underneath the Family
bullet point, listing their name and phone number, like this:
Tip: You'll need to use HTML for the inner bulleted list, as wikitext lists can't be interleaved successfully with $list
widgets. While it's possible to make everything show up correctly while still writing the outer bulleted list in wikitext, if you're struggling with the formatting, it may be easier to switch the outer list to an HTML list as well.
As a reminder, to nest lists in HTML, put another <ul>
opening tag inside an <li>
tag.
In Ex:MacroAdjacency within the Macros section, we found that this attempt to use a simple variable instead of a macro to compose a Wikipedia link didn't work:
<$set name="wikipedia" value="https://en.wikipedia.org/wiki/">
<<wikipedia>>Aardvark
</$set>
We now have the tools needed to accomplish this without a macro. Your solution should display a link to the Aardvark article which has been built from the wikipedia
variable shown above and the constant part Aardvark
, but without using a macro.
addsuffix
.a
, which creates an anchor, including a link. The form of this tag is as follows:<a href="the URL">the link text</a>
go to answer
Make the solution of the previous exercise into a separate WikipediaLinkTemplate
tiddler that can be transcluded, so that it can be used for creating links to more things than just aardvarks. As we learned in Ex:VariableTransclusion, variable values will carry across transclusion boundaries, so refer to the value of a variable called articleName
to decide what article to link to.
While you're at it, make this template more robust by getting the value https://en.wikipedia.org/wiki
from another tiddler; this way, we can reference the base URL of Wikipedia from other places, and only have to update it in one place if it changes.
Modify the template you created in Ex:WikipediaLinkTemplate so that if the articleName
variable is not defined, the article name will instead be taken from the articlename
field of the current tiddler.
else
filter operator, which adds a constant string to the pipeline if there are no input tiddlers, will be useful here. You will also need to put !is[blank]
before the else
operator – we'll explain why once you've completed this exercise.Create a tiddler called WikiStatistics
that shows the following pieces of information in a bulleted list:
To complete the last one, you'll need to review the list of Mathematics Operators on the filter operators manual page.
go to answer