Cant explain this (how to find field values including empty)

Have a set of tiddlers having a field, status, which contains a string, like Sold, On Consignment or it is empty.

I am looking to display only those tiddlers not have a status of Sold nor On Consignment.

The following code doesn’t work.

<<list-links filter:"[all[]]:filter[get[status]compare:string:ne[Sold]compare:string:ne[On Consignment]]">>

Try this:

<<list-links filter:"[all[]has:field[status]] :filter[{!!status}!match[Sold]!match[On Consignment]]">>

Notes:

  • The first filter run, [all[]has:field[status]], returns all tiddlers that have a status field. Note that has[status] is only true if the field is not empty, while has:field[status] is true as long as the status field exists, even if it is empty.
  • Similarly, in the second filter run, the get[status] filter operator only returns a value if the field is not empty. However, there is no equivalent get:field[status] that will return empty status fields. To address this, use {!!status} which always returns a value even if the field is empty or doesn’t exist.
  • Also, for simple string comparisons, you can use the more succinct !match[...] filter operator rather than compare:string:ne[...]. Note that both of these filters are case-sensitive. If you want to do case-insensitive comparisons, you can add a lowercase[] operator, and then compare with lower case string literals, like this:
<<list-links filter:"[all[]has:field[status]] :filter[{!!status}lowercase[]!match[sold]!match[on consignment]]">>

enjoy,
-e

@EricShulman:

Your solution is cleaner and more understandable, but it’s not clear to me why the original didn’t work.

Can you shed light on that?

I’m with you, @Scott_Sauyet , from the documentation and examples, I would have expected my code to work and can not understand why it isn’t.

Also, @EricShulman , if "has[status] is only true if the field is not empty" is true then why not just use a !has[status]? That would seem simpler.

Thank you for your explanations though, appreciated.

bobj

@Scott_Sauyet and @Bob_Jansen

The original code didn’t work because the :filter[get[status]...] only retains tiddlers that have a non-blank status field. That’s why {!!status} was needed.

Using [all[]!has[status]] would find all tiddlers with a blank status field AND those tiddlers that don’t have any status field at all. The result would end up listing nearly all non-shadow tiddlers in your wiki!

For the specific goal in the OP, you could also write the following:

<<list-links filter:"[all[]has:field[status]status[]]">>

which says: “find all tiddlers that actually have a status field where the status field is blank”. Of course, this assumes that status values are ONLY “Sold”, “On Consignment”, or “” (blank). If there are other possible values that you wanted to list, then the solution I previously posted would be the way to go.

Note again, that if you were to use just:

<<list-links filter:"[all[]status[]]">>

you would get “all tiddlers that have a blank or missing status field”.

-e

1 Like

Thank you very much!

– Scott

thank you @EricShulman . After I posted the previous reply, I realised that !has[status] would not work for the reasons you outlined.

So, two ne compares in a row should work if it gets the list of required tiddlers? I realise you suggest using match instead.

bobj

One last filter variation that achieves the original goal and doesn’t need to use a separate :filter[...] run:

<<list-links filter:"[all[]has:field[status]!status[Sold]!status[On Consignment]]">>

-e

2 Likes

Eric,

I would have thought that your latest example, although it would work, is has a redundancy. The first condition of status[Sold] would mean no other tiddler would be selected and thus the !status[On Consignment] is redundant.

Bobj

Eric,

Please ignore my last response, I misread your filter.

Bobj