How to use the $set widget properly with a "not missing" and "empty" filter?

212 views
Skip to first unread message

S. S.

unread,
Mar 30, 2019, 12:17:57 PM3/30/19
to TiddlyWiki
Within a macro, I am trying to determine if a parameter is empty, and then set a variable based on knowing that it is empty.

I came across the Google Group post from a last month: Check the Blank Macro parameter
\define mm(newField)
<$list filter="[<__newField__>] -[[]]">

Do my job!
</$list>
\end


<<mm test>>

So I tried using something based on that. Pasting the below into a new tiddler on tiddlywiki.com shows the issue:

\define test(tiddler)
<$set name="result" filter="[[$tiddler$]] -[[]]" value="Why is this variable set when the filter ''is not missing'' and ''it's empty''?">

The description of the ''value'' attribute of the `$set` widget says: The value to assign to the variable if the filter is missing or ''//not empty//''

tiddler
=$tiddler$  

result
=<<result>>

<$list filter="[[$tiddler$]] -[[]]" emptyMessage="See, the filter shows it's Empty">
</$list>
</
$set>
\end

<<test>>


I don't understand where I've gone wrong. I'd appreciate some advice.
Thanks.


S. S.

unread,
Mar 30, 2019, 4:59:14 PM3/30/19
to TiddlyWiki

I found a solution here: [TW5] Using conditional assignment mode of SetWidget to check empty strings

Either of the below work, and I chose the former.
filter="[enlist[$tiddler$]]"
 filter
=" $tiddler$"

Regards

TonyM

unread,
Mar 30, 2019, 7:55:21 PM3/30/19
to TiddlyWiki
Another related approach may be something discussed in recent weeks

The content of the <$view> widget is displayed if the field or property is missing or empty.

So you can go ahead and display a value if its present, otherwise the content of the view widget can be used to handle its creation. https://github.com/Jermolene/TiddlyWiki5/issues/3789

Regards
Tony

Presently the view widget only accepts tiddler and fieldnames but I am asking it also accept variables. 

Jeremy Ruston

unread,
Mar 31, 2019, 10:46:22 AM3/31/19
to tiddl...@googlegroups.com
Hi SS

The logic used by the set widget to determine the result assigned to the variable is as follows:

1. If the "tiddler" attribute is present and not blank, then:
1a. If the "subtiddler" attribute is also present and not blank, then get the subtiddler from the specified tiddler, otherwise just get the tiddler itself
1b. If the "field" attribute is present then return return the value of that field, or the value of the "emptyValue" attribute if the field is blank or missing
1c. Otherwise, if the "index" attribute is present, return the value of the specified index, or the value of the "emptyValue" attribute if the index is blank or missing
1d. Otherwise, return the text field of the tiddler, or the value of the "emptyValue" attribute if the text field is blank or missing

2. If the "filter" attribute is present and not blank, then evaluate the results of the filter, and:
2a. If the "value" attribute is present and the filter results are not empty, return the value of the "value" attribute (even if the "value" attribute is blank)
2b. If the "value" attribute is present and the filter results are empty, return the value of the "emptyValue" attribute, if present, otherwise return a blank result
2c. If the "value" attribute is not present, then if the "select" attribute is a valid number it is used to retrieve a specified result from the filter
2d. If the "value" attribute is not present, and the "select" attribute is not a valid number, and the filter results are not empty, then the entire filter results are returned (using double square brackets quoting around any results that include spaces)
2e. If the "value" attribute is not present, the "select" attribute is not a valid number, and the filter results are empty, then the value of the "emptyValue" attribute is returned (or blank if it is not present)

3. If neither the "tiddler" or "filter" attributes are provided, return the value of the "value" attribute, or the value of the "emptyValue" attribute if the "value" attribute is blank or missing

Perhaps it would be clearer expressed as a series of examples...

Best wishes

--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/1867389e-59de-4b9e-b8e6-6ecd9212d92e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mohammad

unread,
Mar 31, 2019, 12:12:00 PM3/31/19
to TiddlyWiki
Added to TW-Scripts
To unsubscribe from this group and stop receiving emails from it, send an email to tiddl...@googlegroups.com.

Mohammad

unread,
Mar 31, 2019, 12:17:46 PM3/31/19
to TiddlyWiki
Hi S.S.,
 If you add the Jeremy explanation to your documentation project, I appreciate to update us here!

Thank you

Eric Shulman

unread,
Mar 31, 2019, 1:17:42 PM3/31/19
to TiddlyWiki
On Sunday, March 31, 2019 at 7:46:22 AM UTC-7, Jeremy Ruston wrote:
Perhaps it would be clearer expressed as a series of examples...

Here's my take on examples plus a little bit of re-arranging and editing of Jeremy's descriptions...
 
1. If the "tiddler" attribute is present, get the text of the tiddler, or the value of the "emptyValue" attribute if the text field is blank or missing
<$set name="myvar" tiddler="SomeTiddler" emptyValue="sometext">
 
1a. If the "subtiddler" attribute is present, get the text of the subtiddler from the specified tiddler, or the value of the "emptyValue" attribute if the subtiddler text is blank or missing
<$set name="myvar" tiddler="SomeTiddler" subtiddler="SomeSubTiddler" emptyValue="sometext">

1b. If the "field" attribute is present, get the value of that field, or the value of the "emptyValue" attribute if the field is blank or missing
<$set name="myvar" tiddler="SomeTiddler" field="somefield" emptyValue="sometext">

1c. If the "index" attribute is present, get the value of the specified index, or the value of the "emptyValue" attribute if the index is blank or missing
<$set name="myvar" tiddler="SomeTiddler" index="somefield" emptyValue="sometext">
 
2. If the "filter" attribute is present and not blank, return the entire filter results using double square brackets quoting around any results that include spaces
<$set name="myvar" filter="[somefilter[]]">
 
2a. If both the "filter" attribute and the "value" attribute are present and the filter results are not empty, return the value of the "value" attribute, otherwise return blank
<$set name="myvar" filter="[somefilter[]]" value="somevalue">
 
2b. If both the "filter" attribute and the "emptyValue" attribute are present, return the entire filter results using double square brackets quoting around any results that include spaces, or the value of the "emptyValue" attribute if the result is empty
<$set name="myvar" filter="[somefilter[]]" emptyValue="sometext">
 
2c. If the "filter" attribute, the "value" attribute, and the "emptyValue" attribute are present, return the value of the "value" attribute, or the value of the "emptyValue" attribute if the result is empty
<$set name="myvar" filter="[somefilter[]]" value="somevalue" emptyValue="sometext">
 
2d. If both the "filter" attribute and the "select" attribute are present and the "select" attribute is a valid number "N", return the "Nth" result from the filter
<$set name="myvar" filter="[somefilter[]]" select="3">
 
3. If neither the "tiddler" or "filter" attributes are provided, return the value of the "value" attribute, or the value of the "emptyValue" attribute if the "value" attribute is blank or missing
<$set name="myvar" value="somevalue" emptyValue="sometext">

-e

Mohammad

unread,
Mar 31, 2019, 1:19:37 PM3/31/19
to TiddlyWiki
Hi Eric,
 Excellent as always!

Best
Mohammad

S. S.

unread,
Apr 1, 2019, 8:36:18 AM4/1/19
to TiddlyWiki

I have copied and pasted from Eric's post - and added in some from Jeremy's post, and a few of my own observations.
I am sure this is still not perfect.

I hope this formats properly. Google Group's functionality and reliability, and this posting editor must be one of the weakest links in their formidable arsenal!
But then who are we to complain too loudly - free is not really free.


1. If the "tiddler" attribute is present:
1a. Get the text of the tiddler, or the value of the "emptyValue" attribute if the tiddler attribute value or tiddler text field is empty or missing

<$set name="myvar" tiddler="SomeTiddler" emptyValue="sometext">
1b. If the "subtiddler" attribute is present, get the text of the subtiddler from the specified tiddler, or the value of the "emptyValue" attribute if the tiddler or subtiddler is blank or missing or the subtiddler text field is blank

<$set name="myvar" tiddler="SomeTiddler" subtiddler="SomeSubTiddler" emptyValue="sometext">
1c. If the "field" attribute is present, get the value of that field, or the value of the "emptyValue" attribute if the tiddler or field is blank or missing

<$set name="myvar" tiddler="SomeTiddler" field="somefield" emptyValue="sometext">
1d. If the "index" attribute is present, get the value of the specified index, or the value of the "emptyValue" attribute if the tiddler or index is blank or missing

<$set name="myvar" tiddler="SomeTiddler" index="somefield" emptyValue="sometext">
1e. If the "tiddler" attribute is present and blank and the filter is present and blank, then return the emptyValue, or blank if there is no emptyValue
<$set name="myvar" tiddler="" filter="[somefilter[]]" emptyValue="sometext">
1f. If the "tiddler" attribute is present and blank and the filter is present and not blank, then return the entire filter result, & see below for how select behaves with a filter
<$set name="myvar" tiddler="" filter="[somefilter[]]">
1g. If the "tiddler" attribute is present and blank and the value attribute is present and blank, then return the emptyValue, or blank if there is no emptyValue
<$set name="myvar" tiddler="" value="" emptyValue="sometext">
1h. If the "tiddler" attribute is present and blank and the value attribute is present and not blank, then return the value
<$set name="myvar" tiddler="" value="somevalue">

2. If the "filter" attribute is present and not blank, it is evaluated and:
2a. If there is a non blank filter result, return the entire filter results using double square brackets quoting around any results that include spaces

<$set name="myvar" filter="[somefilter[]]">
2b. If the "value" attribute is present, the filter's result is ignored and the value of the "value" attribute (even if it is blank) is returned.

<$set name="myvar" filter="[somefilter[]]" value="somevalue">
2c. If there is a blank filter result and the "emptyValue" attribute is present, return the value of the "emptyValue" attribute

<$set name="myvar" filter="[somefilter[]]" emptyValue="sometext">
2d. If the "value" attribute and the "emptyValue" attribute are present, if there is a non blank filter result, return the value (even if it is empty), or if the filter result is empty, return the emptyValue

<$set name="myvar" filter="[somefilter[]]" value="somevalue" emptyValue="sometext">
2e. If both the "filter" attribute and the "select" attribute are present and the "select" attribute is a valid number "N", return the "Nth" result from the filter

<$set name="myvar" filter="[somefilter[]]" select="3">
2f. If both the "filter" attribute and the "select" attribute are present and the "select" attribute is a blank, return the entire filter results

<$set name="myvar" filter="[somefilter[]]" select="">
2g. If both the "filter" attribute and the "select" attribute are present and there is a non blank filter result and the "select" attribute is not a valid number, a blank is returned even if there is an emptyValue
<$set name="myvar" filter="[somefilter[]]" select="1000" emptyValue="this won't be returned">
2h. If both the "filter" attribute and the "select" attribute are present and there is a blank filter result, if there is an emptyValue it is returned, otherwise a blank is returned.
<$set name="myvar" filter="[someBadfilter[]]" select="1000" emptyValue="this will be returned">

3. If neither the "tiddler" or "filter" attributes are provided, return the value of the "value" attribute, or the value of the "emptyValue" attribute if the "value" attribute is blank or missing
<$set name="myvar" value="somevalue" emptyValue="sometext">

Note: This does not exactly describe the behaviour: in Jeremy's 2b.
If the "value" attribute is present and the filter results are empty, return the value of the "emptyValue" attribute, if present, otherwise return a blank result
Testting shows: If there is a value attribute & no emptyValue attribute, the value is returned irrespective of the filter's result.


Thanks Jeremy for laying out the sequence and to Eric for providing the actual examples!

Note:- It is sometimes difficult to ascertain if the filter attribute as used in the $set widget is actually empty.
It may be that a filter in a $list widget shows a given filter as empty, but that does not necessarily mean the same filter used as a value of the filter attribute in the $set widget will show empty.

That is how this topic started off! See the 2nd post in the discussion to see how it was solved.

Cheers!

Mohammad

unread,
Apr 1, 2019, 11:15:35 AM4/1/19
to TiddlyWiki
Many thanks s.s,
It is good to put the link to documentation wiki here!

--Mohammad

Jeremy Ruston

unread,
Apr 1, 2019, 11:26:24 AM4/1/19
to tiddl...@googlegroups.com
Hi SS

That’s great, thank you.

> Testting shows: If there is a value attribute & no emptyValue attribute, the value is returned irrespective of the filter's result.

I can confirm that behaviour, and I think it’s a bug. But… I’m not 100% sure that we should fix it; it might be better just to revise the docs at this point (the observed behaviour is simpler to describe in the docs).

Best wishes

Jeremy

S. S.

unread,
Apr 4, 2019, 8:20:39 PM4/4/19
to TiddlyWiki

The set widget is very useful for choosing between multiple options.
Understanding the logic of what combinations of the $set widget's attributes produce the desired outcome is essential to using it for such a requirement.
The discussion above was quite a revelation.

Here's a possible use.

If A is not empty, chose A
   If A is empty, chose B
      If B is empty, chose C
         If C is empty, chose D

A real case secenario occurred within the date() macro:

In the macro, I wanted to choose a template based on:
If there is a template-day parameter ( $template-day$ )
   Use that
   If NO template-day parameter
      Use the template parameter ( $template$ )
      If NO template parameter
         Use the Custom Settings field value (stored in    tiddler: date-settings-tiddler    field: template-day )
         If NO Custom Settings
            Use the template default variable ( <<template-day-default>> )

<$set name="temp" tiddler="date-settings-tiddler" field="template-day" emptyValue=<<template-day-default>>>
   <$set name="temp-template" filter="[enlist[$template$]]" value="$template$" emptyValue=<
<temp>>>
      <$set name="template" filter="[enlist[$template-day$]]" value="$template-day$" emptyValue=<
<temp-template>>>

         Code using <
<template>>

      </$set>
   </$set>
</$set>

Note how the $set flow is an exact reverse of the logical requirement, where the most important variable ( template-day ) is tested last.

So, for those interested, attached is a: Set Widget Tester for attribute precedence tiddler.
Drag & drop it into your TiddlyWiki or tiddlywiki.com & hopefully quickly check the result of any combination of the set widget's parameters.

Regards.
Set Widget Tester for attribute precedence.tid

TonyM

unread,
Apr 4, 2019, 10:04:03 PM4/4/19
to TiddlyWiki
S S

I often use a variation of this when making my own macros to allow it to use current tiddler or another if provided. Basically it provides a default of the current tiddler

\define mymacro(tiddlername)
<$set name=selected-tiddler value="$tiddlername$" emptyValue=<<currentTiddler>> >
Action: <<selected-tiddler>>
</$set>
\end

<<mymacro>>
<<mymacro "another tiddler">>

This also illustrates another design principal, I almost always write my macros to operate on the current tiddler such that if placed in wikitext a list without a variable set the macros operate on the changing current tiddler, or it can be given a specific tiddler. If I use a variable in the list it uses the currentTiddler and the list will not change the currentTiddler value

Thanks for sharing.

Regards
Tony

Mohammad

unread,
Apr 5, 2019, 1:30:11 AM4/5/19
to TiddlyWiki
Hi S.S,
 This is great!
You can visually and interactively play with $set and see the result!

Thank you
Reply all
Reply to author
Forward
0 new messages