List filter -- and/or?

Is it possible to write a simple list filter to find TagA and/or TagB?

I’ve been finding old posts that suggest not without using a TOC thingy (which I haven’t played with yet).

IF it’s simple, great BUT my current wikitext-coding comprehension is limited to basic $List-Checkbox… so if it’s not simple, I’ll find another way to sort out my need.

And or is easy because you can ask if TagA else TagB

[tag[TagA]] :else[tag[TagB]] which will return a value if TagA and/or TagB and no value if not.

<$list filter="[all[current]tag[TagA]] :else[all[current]tag[TagB]]">

This is TagA and/or TagB
</$list>

But I presume you are asking if the current tiddler has TagA and/or TagB so we use all[current]

You can’t separate the cases when the current tiddler has TagA and TagB it will just return TagA, but we can do more if needed.

Assuming “TagA” means “all tiddlers tagged A”
and that “and/or” does not mean XOR
then it is as simple as this:

[tag[A]] [tag[B]]

Thank you for your responses. Clearly there’s something wrong with my syntax/understanding… and again, I haven’t asked the right question.

@TW_Tones — by “current” tiddler do you mean the tiddler carrying the $list?

  • So, NO — not current tiddler.

  • But I also tried adding the tags to what I think you mean by current tiddler, and nothing displays in a list… until

  • so your suggested code (cut and paste) is not working for me. Don’t know why. Found resources for “all operator” and replaced “current” with “tiddlers”. This created a list of “This is TagA and/or TagB” repeated 20 times.?

  • How can I get your example to work (for future reference) and what does :else do? (resources for “else operator” and “examples” didn’t help me understand).

@twMat — maybe I do mean XOR (but not sure)
Your code only displays IF both tags are present in a tiddler.

I want to list any tiddlers that have either TagA and / or TagB — but in most, if not all cases, my tiddlers will only have one of the tags — so an OR statement might suffice… but How?

Here’s my code so far…

<$list filter="[!has[draft.of]tag[TagA]tag[TagB]sort[title]]" />

ALSO - can TW display syntax color/highlight similar to the way this forum shows precode examples?

Let’s build your filters step-by-step…

First, to get a list of all tiddlers tagged with “TagA”, you can write: [tag[TagA]], and to get a list of all tiddler tagged with “TagB”, you can write: [tag[TagB]]. Then, you can combine these separate filter runs, like this:

[tag[TagA]] [tag[TagB]]

Note how each filter run has its own enclosing outer square brackets, and the filter runs are separated by a space. Each filter run produces a list of matching tiddlers, which are then combined to produce the final results. Note that by default, the filter syntax automatically removes duplicates from the final results, so if the same tiddler is tagged with both “TagA” AND “TagB”, it will still only occur ONCE in the final results. Thus, the above combined filter is effectively saying “find all tiddlers that have TagA OR TagB (or both)”, which is what you want.

In contrast, suppose you were to write:

[tag[TagA]tag[TagB]]

where there is only one set of enclosing outer square brackets and no space between the two tag[...] operators. This will find all tiddlers that have TagA… and then only keep those tiddlers that ALSO have TagB. This is effectively saying “find all tiddlers that have BOTH TagA AND TagB”

To complete your filter syntax, all that remains is to eliminate any “draft” tiddlers, and sort the results by title.

To remove the draft tiddlers from the list, you can add a filter run, -[has[draft.of]]. Note the leading “-” sign before the enclosing square brackets of this filter run. This means “remove any tiddlers that match the following filter”.

To sort the final results, you can add a filter run, +[sort[]]. Note the leading “+” sign before the enclose square brackets of this filter run. This means “apply the following filter to all tiddlers matched so far”. Note also that the title parameter can be omitted from the sort[...] operator, since that is the default field used when no field name is specified.

Take note that the tag[...] operator is highly optimized by the TWCore which automatically caches an “index” of all tiddlers by tag, so it is very efficient to find tagged tiddlers. However, the has[...] and sort[...] operators, while still reasonably fast, are less performant because they need to actually retrieve individual tiddler data to examine each of their field values. Thus, it is better to check for the draft.of field and sort the results AFTER reducing the list of tiddlers by matching tags first.

Putting it all together, your final filter syntax should be:

<$list filter="[tag[TagA]] [tag[TagB]] -[has[draft.of]] +[sort[]]" />

Hope this explanation helps… let me know how it goes.

enjoy,
-e

1 Like

No, that is not correct (did you try it out?) My filter consists of two independent runs. Note the space between the two filters.

So you do indeed want a regular “and/or” (“either or both”) which is a logical OR (not XOR)

Try this:

<$list filter="[tag[TagA]] [tag[TagB]] +[!has[draft.of]sort[title]]" />

This gathers up all tids taggad TagA and all tids tagged TagB and then forces the total result to go through the last filter run to weed out drafts and then sort.


EDIT: Oups, I just now saw Erics answer. I guess you can compare both of our answers, they should both work.

1 Like

@EricShulman – Excellent, thanks. Your explanation of the separate tag runs and pointing out the logic of what gets processed first really helps me understand more about syntax.

@twMat – yes NOW I see since Eric pointed that out too. Thank you.

You’ve both indicated using - and + but in slightly different ways — which is great because it clarifies what is taking place. Until now I’ve been unaware that I could connect different processes like that, so yes now I recognised the importance of the “space” for readability (although it still works if the space is omitted).

So far I’ve only used $list as one string…

<$list filter="[!has[draft.of]tag[ToDO]!tag[done]sort[created]]">

and now tested rewriting that in various ways…

<$list filter="[tag[ToDO]] -[tag[done] +[!has[draft.of]sort[created]]" />

Thank you.