In an edit template, I wanted to use a filter that says if the current tiddler has either field A or field B. This is akin to (A AND (B OR C)). So I started from:
<$list filter="[all[current][[has:field[first-met-on]] [has:field[last-met-on]]]]">
What is the correct way of writing this?
Using De Morgan's laws - Wikipedia, we can convert (A AND (B OR C))
into (A AND B) OR (A AND C)
. So, we can write your filter as two filter runs: <$list filter="[<currentTiddler>has:field[first-met-on]] [<currentTiddler>has:field[last-met-on]]">
However, this is not quite enough, as this could potentially fulfill BOTH conditions, which would result in the $list contents being rendered twice. To address this, we can add +[limit[1]]
to the end of the filter.
Thus, this is the general filter pattern for invoking an OR conditional:
<$list filter="[<currentTiddler>has:field[first-met-on]]
[<currentTiddler>has:field[last-met-on]]">
+[limit[1]]">
On a related note, are the following two just the same?
<$list filter="[all[current]tag[Contact]]">
<$list filter="[<currentTiddler>tag[Contact]]">
Yes, they are logically equivalent. (Note: you left off the outer brackets in the second line… I fixed it.)
Potentially the only difference is one of performance. Both forms of syntax perform a variable lookup, which is highly optimized in the TWCore JS code.
<currentTiddler>
is slightly more direct, in that it immediately invokes options.widget.getVariable(title)
(see $:/core/modules/filters/getvariable.js).
In contrast, [all[current]]
does do slightly more processing to handle a variety of other possible use-cases such as [all[tiddlers+shadows]]
or [all[missing]]
(see $:/core/modules/filters/all.js and $:/core/modules/filters/all/current.js). Ultimately, however, [all[current]]
also invokes options.widget.getVariable("currentTiddler")
to actually get the current tiddler’s title.
You should use whichever syntax makes conceptual sense to you. I personally prefer [<currentTiddler>...]
.
enjoy,
-e