Filter question: get caption else use title

326 views
Skip to first unread message

Saq Imtiaz

unread,
Jun 14, 2021, 10:08:58 AM6/14/21
to TiddlyWiki
I feel like there must be a very simple way to do this that I am missing.

Given an ordered list of tiddler titles, in a single filter expression, replace the title with the caption if there is one, else keep the title - without changing the order.

The only solution I came up with is convoluted (on pre-release):

[tag[Widgets]] :reduce[get[caption]else{!!title}format:titlelist[]addprefix[ ]addprefix<accumulator>] +[enlist-input[]]

where tag[Widgets] is a good stand-in for testing purposes for the ordered list, as not all of these tiddler on https://tiddlywiki.com/prerelease/ have captions but most do.
Is there a simpler alternative?

Cheers,
Saq

TW Tones

unread,
Jun 14, 2021, 7:00:25 PM6/14/21
to TiddlyWiki
Saq,

Is the demand for a single filter expression a needed constraint?, because a filtered transclusion can be used to display the caption or title? Or am I missing something?

<$list filter="[tag[Widgets]]">
  <$link><$text text={{{ [all[current]get[caption]else[{!!title}]] }}}/></$link><br>
</$list>

Whilst we can squeeze more out of filters it is easy to overloads them, In my above list the list filter relates to the selection the filtered transclusion to the display of the item. They are distinct functions and need not be combined. 

Regards
Tones

TW Tones

unread,
Jun 14, 2021, 7:02:32 PM6/14/21
to TiddlyWiki
Opps  [all[current]get[caption]else{!!title}] 

Saq Imtiaz

unread,
Jun 14, 2021, 7:18:48 PM6/14/21
to TiddlyWiki

Is the demand for a single filter expression a needed constraint?

 Yes. It is going to be used in a context where other wikitext cannot be introduced. 
It is possible with the filter expression I posted but I'm curious if I've missed a simpler solution.

TW Tones

unread,
Jun 14, 2021, 8:37:02 PM6/14/21
to TiddlyWiki
Saq,

Could you give some idea of how/why It is going to be used in a context where other wikitext cannot be introduced. ?
  • Do you want it in a "filtered transclusion"? see below

Of course the following does what you want but the currentTiddler is not available inside the list.

<$list filter="[tag[Widgets]sort[title]] +[get[caption]else{!!title}]">

</$list>

This also achieves the same?
In the template you have access to the current tiddler, in the same way as my first response with an inline template?

<$list filter="[tag[Widgets]sort[title]]" template="caption-or-title">

</$list>

Where caption-or-title contains
{{{ [all[current]get[caption]else{!!title}] }}}<br>

In a filtered transclusion you can use a template
{{{ [tag[Widgets]sort[title]]||caption-or-title}}}

I am interested in the challenge.

Regards
Tones

TW Tones

unread,
Jun 14, 2021, 9:18:51 PM6/14/21
to TiddlyWiki
Saq Et al,

Some thinking an experiments. I miss the TWC For Each Tiddler macro, which the following comes closer to. Such changes could be added to a new widget, as the ;list widget is busy, similar to the list Widget such as "list-report Widget", permitting more than one value to be extracted from inside the filter.

On prerelease we now have a counter variable which allows the following;
<$list filter="[tag[Widgets]sort[title]]" counter=item>
  <<item>>. <$link/><br>
</$list>

In the above you can see there are two variables available inside the list, the currentTiddler (or named variable)  and now the named counter in this case item.

The thing is we use the title or currentTiddler interchangeably with only one output. We can addprefixes and generate new tiddler titles, extract a field but do not have access to the tiddler title we used to generate it. I was thinking what if we could assign the currentTiddler (result) to a variable in a filter making the currentTiddler available in the list/template.

<$list filter="[tag[Widgets]sort[title]var:varname[]] +[get[caption]else{!!title}]">
  <<currentTiddler>> <<varname>><br>
</$list>
OR
<$list filter="[tag[Widgets]sort[title]] :var:description{!!description}] +[get[caption]else{!!title}]">
   <<currentTiddler>> - <<description>> <br>
</$list>

In the Above cases for each iteration of the list the currentTiddler would be the caption or title, but varname would contain the original tiddler title, keeping in mind you may not see it if the given tiddler is eliminated from the output.

Basically for each iteration of the first run above the output title will be stored in varname and passed on to the next run.
If this could be done more than once a lot could be extracted from one list.

Using counter
You could actually use the counter (less 1) as the select value in a set statement, to turn the counter into a reference to a tiddler.

<$set name=widget-list filter="[tag[Widgets]sort[title]]">
<$list filter="[enlist<widget-list>]" counter=item>
  <<item>>. <$link/> {{!!caption}}
''Use set select with filter=<<widget-list>> here!''<br>
</$list>
</$set>

Tones

Saq Imtiaz

unread,
Jun 15, 2021, 7:12:40 AM6/15/21
to TiddlyWiki
@Tony

Could you give some idea of how/why It is going to be used in a context where other wikitext cannot be introduced. ?

Explaining my specific use case would be quite complex as it is part of a much larger application. The filter I've described in this thread is a simpler one that presents an analogous issue, where you want to replace an input title with one if its field if that field exists, otherwise retain the original title. All without changing the list order. It could just as easily be get[parent] instead of get[caption] if that helps with conceptualizing the problem.

There are plenty of general use cases where a filter needs to provide the necessary output independently of other wikitext. For example:
  • As input to a widget that accepts a filter attribute.
  • In a configuration tiddler that accepts a filter. See for instance $:/config/syncFilter or $:/core/ui/DefaultSearchResults.
  • As a filter meant to be used elsewhere via the subfilter[] operator
  • When trying to optimize refresh performance in a large and complex widget tree and wanting to use as few widgets as possible.
I am interested in the challenge.

A good way to frame the constraints is that it should be possible to type the filter directly into the Filter tab in AdvancedSearch. 

TW Tones

unread,
Jun 16, 2021, 12:50:18 AM6/16/21
to TiddlyWiki
Saq,

Am I correct ? I think this is behind the problem you have of simplification. Otherwise this would be sufficient [tag[Widgets]get[caption]else[title]]

Typically a filter returns a list of titles, even if they are virtual, strings that are not actual tiddlers. operators permit references to other values such as tiddler content, variables and fields. These allow complex conditional selections or titles to be generated. The filter functionality has being developed much further so the output of run can be numbers, modified strings and titles etc... The result of  filter in the list widget is returned via the currentTiddler/named Variable or the emptyMessage ONLY. 

From the above we can process each title and reference each titles additional content using the title as a key. For example we can access the caption in side the list {{!!caption}} this is the display process.

Since filters are so rich in functionality we can generate other lists, one may be a set of tiddlers with caption OR title as the output,  this is returned as the title via the currentTiddler/named Variable ONLY. Currently when you make this decision to extract secondary data in a filter you may loose access to the key (the tiddler title). The feature to do this is great but it is mixing the selection process with the display process. This is fine but presently the original tiddler title if present is lost as the display is the caption/title output not the always the title of the tiddler, you may loose the key.

Prerelease shows how a second value can be returned for each item in the list, in this case the counter number. In some filters it would be good if an additional variable that passed on the original tiddler title, in your example all  [tag[Widgets]]. sure some of these tiddlers will be eliminated, and there name not accessible, because the list never displays them, but the ones it does it would be useful. Sometimes the titles are virtual strings, but making these available may also be helpful.

If you are prepared to split selection and display (in your case no) or nest lists there is not problem. We could write a macro with two filters, one selection one display and this would not be an issue.

Is this in your problem scope?, or divergent?, What do you think?

Tones

PMario

unread,
Jun 16, 2021, 2:39:24 AM6/16/21
to TiddlyWiki
Hi Saq,
That's a tricky filter. You use the capability of the "reduce" filter, that it has access to the "currentTiddler" inside the filter run.

If "elseXX" would have the same info it would be as simple as this.

[tag[Widgets]] +[get[caption]elseXX{!!title}]

I think, the usecase is "generic" enough, to discuss a new elseX operator, that has this info.

Just a thought
-mario

Saq Imtiaz

unread,
Jun 16, 2021, 2:42:18 AM6/16/21
to TiddlyWiki
 
Am I correct ? I think this is behind the problem you have of simplification. Otherwise this would be sufficient [tag[Widgets]get[caption]else[title]]

I am at a loss as to what you are trying to say here. The filter you provide however would not under any circumstance return the desired result, even if you changed [title] to {!!title}.
 
If you are prepared to split selection and display (in your case no) or nest lists there is not problem. We could write a macro with two filters, one selection one display and this would not be an issue.

I believe I have explained quite clearly that it isn't always a matter of choice to split things, or even as simple as demarcating things into just selection and display.  Furthermore, there isn't any problem to start with. My first post already contains a filter expression that returns the desired result. I wanted to see if someone could spot a simpler filter that might do the same trick. I would welcome any input along those lines within the stated constraints, otherwise I don't see any reason to continue this discussion. 

Saq Imtiaz

unread,
Jun 16, 2021, 3:03:14 AM6/16/21
to TiddlyWiki
@pmario thank you for taking a look. Oddly enough, this came up now as I was trying to see if I could replace a custom filter with the new filter capabilities in the core.

There are actually multiple ways that we could address this with a new filter but I haven't had the chance to think through them and figure out which would have the most universal utility. I'll post something on Github when I get the chance. 

Thank you.

TW Tones

unread,
Jun 16, 2021, 7:45:51 PM6/16/21
to TiddlyWiki
Saq,

Well then either I don't understand what you are saying and/or you don't understand what I am saying (or both).

as far as I can see I can replicate you filter with [tag[Widgets]sort[]] +[get[caption]else[{!!title}]] while neither this or your filter provides links to the original tiddler.

Your question was how to get a similar result to your filter that you give an example for?, but you do not specifically state what result you are looking for. As a Result I speculated and came to think you want an intermediate result while retaining the currentTiddler. I then go on to talk about how this may be achieved in the future, in a simplified form of your filter which while an impressive use of the new filters it is hardly readable for most.

Perhaps I have not answered your question, but I did my best and put in some though and effort. Always with a view to improving tiddlywiki.

Regards
Tones

PMario

unread,
Jun 17, 2021, 12:29:20 AM6/17/21
to TiddlyWiki
On Thursday, June 17, 2021 at 1:45:51 AM UTC+2 TW Tones wrote:

as far as I can see I can replicate you filter with [tag[Widgets]sort[]] +[get[caption]else[{!!title}]] while neither this or your filter provides links to the original tiddler.

That doesn't produce the same results. Your filter returns 48 elements and Saqs filter returns 52.

[tag[Widgets]] also returns 52 elements.

+[get[caption]else[{!!title}]] ... doesn't work the way as it seems. It doesn't use the title of the input it uses the title of the tiddler where the filter is used.

reduce has some special "internal" variables. See: https://tiddlywiki.com/prerelease/#reduce%20Operator

-mario.
Reply all
Reply to author
Forward
0 new messages