I need a filter that will tell me if the current tiddler contains any tag from a list of tags. This list of tags are in a text field of a tiddler named $:/tags/caption/title
Any help would be appreciated. Thanks,
Craig
I need a filter that will tell me if the current tiddler contains any tag from a list of tags. This list of tags are in a text field of a tiddler named $:/tags/caption/title
Any help would be appreciated. Thanks,
Craig
Try this:
{{{ [enlist{$:/tags/caption/title}] :filter[<..currentTiddler>tag<currentTiddler>] +[then[yes]limit[1]] }}}
Notes:
$:/tags/caption/title
text field contains a space-separated list of tag values and, if a tag contains spaces, it is enclosed in doubled square brackets.:filter[...]
run, <..currentTiddler>
refers to the tiddler in which the entire filter expression is being applied, while <currentTiddler>
refers to each of the “target” tag values enlisted from the text field of $:/tags/caption/title
.:filter[...]
run, a literal value of ‘yes’ is produced.limit[1]
ensures that the final result of the entire filter expression will be either a single “yes” (indicating a matching tag was found), or no value (indicating no matching tags were found).enjoy,
-e
Just because variety is the spice o’ life:
{{{ [{!!title}tags[]] :intersection[enlist{$:/tags/caption/title}] +[join[]then[yes]] }}}
And if we read that filter left to right: for the current tiddler, get the tiddler’s tag titles. Intersect the tiddler’s tag titles with a list of titles from this other tiddler. If there is intersection of one or more titles, then return “yes”.
Is this the start of a new forum section named “WikiText filter code golf”?
Here’s yet another way to do it:
{{{ [enlist{$:/tags/caption/title}tagging[]match{!!title}then[yes]] }}}
Could be shortened to this if the tiddler $:/tags/caption/title was using the list field instead of the text field:
{{{ [list[$:/tags/caption/title]tagging[]match{!!title}then[yes]] }}}
You might also want to check out this thread:
I’ve been using the augmented enlist
operator very extensively ever since, to avoid filter constructs like above and make the code more readable. Nowadays, this might be doable in a similarly neat way with a function, though the JS filter operator will be faster.
Oh man, we could easily play code golf/ping-pong in any thread.
The beauty o’ TiddlyWiki: we can solve a problem in various ways because of TW’s flexibility, and the right way for any one of us is the way that matches the way one happens to think.
Thank you. Much appreciated.
Thanks for all the replies. I asked MS Copilot this question, and the code result was not usable.
Aside: I implemented a template to show either tiddler title or tiddler caption with the title in smaller fontsize in tiddler header. I wanted the user to be able to identify tiddlers where they want the caption field vs the title shown in the tiddler header. Previously, I had this hard coded for a person tiddler. With this solution, they can now configure tiddlers (by providing a list of tags in the configuration section) to do this.
Eg of person tiddler shown using title of the tiddler:
…and an example of the tiddler shown using the caption field (with the title under caption):
I just thought I would add, when writting filters for tags we have a set of operators for tag handling. We can assume that these operators should provide an oportunity to test tags. In this case however we are comparing one list (in a tiddler) with the list of tags, however we only need one to match.
[intags[]]
returns each of the input titles that is in the tags list.
!intags[]
would return titles not in the tags.\function special.tags() [enlist{$:/tags/caption/title}]
\function special.tags() Learning Filters
\function current.tags() [enlist{!!tags}]
\function current.tags() [all[current]tags[]]
* {{{ [special.tags[]] :intersection[current.tags[]] }}} all intersections if any
* {{{ [special.tags[]] :intersection[current.tags[]] +[limit[1]] }}} only one intersection if any, logical yes.
I will explore making a simpler and generic way to test if there is an intersection between two sets/lists where one is the input to the function.
Here I abstract this further (add to above functions)
\function in.function(function) :intersection[function<function>]
* {{{ [special.tags[]] [in.function[current.tags]] +[limit[1]] }}}
the in.function could also be in.function.list, ie any function that generates a list. We add the +[limit[1]]
only to turn it into a test for any (or none) and not “a list of all” in the list that match.