Look for a Simple WikiText: Link Title Based on Several Conditions

I am listing several tiddlers under a tag (currentTag). The links shall be displayed as below

  • Use title of tiddler by default
  • If tiddler has caption use it instead of title
  • If the currentTag has a format field, look into it and use the field specified there
  • If there is a global setting, look into it and use the field specified there

Note i: The format field has priority over global setting
Note ii: If there is no format, no global setting, use caption, if no caption, use title

In brief the priority is as below!

[Format] / [gSetting] / [Caption] / [Title]

If a specified field is empty, then use [Caption] / [Title] priority.

The below code works. Test it on https://tiddlywiki.com. BUT I am looking for a simpler code.

\define currentTag() HelloThere
\define gSetting() $:/config/LinkTitle


<$list filter="[tag<currentTag>]">
<$link to={{!!title}} tooltip=<<currentTiddler>> >
<!--- dispField determines how to show the link title for an item: use specified field in HelloThere, or use global setting -->
<$let dispField= {{{ [<currentTag>get[format]]:else[<gSetting>get[text]] :and[limit[1]] :else[[caption]] }}}
      tv-wikilinks="no" >
<$list filter="[<currentTiddler>get<dispField>trim[]!is[blank]] :filter[<dispField>!match[title]]" variable=null emptyMessage='<$view field="title"/>'>
<$transclude field=<<dispField>> />
</$list>
</$let>
</$link><br>
</$list>

I found this is simpler, but not simplest.

\define currentTag() HelloThere
\define gSetting() $:/config/LinkTitle


<$list filter="[tag<currentTag>]">
<$link to=<<currentTiddler>> tooltip=<<currentTiddler>> >
<!--- dispField determines how to show the link title for an item: use specified field in currentTag, or use global setting -->
<$let dispField= {{{ [<currentTag>get[format]]:else[<gSetting>get[text]] }}} tv-wikilinks="no" >
  <$transclude field={{{ [<dispField>trim[]!is[blank]!match[title]else[caption]] }}}>
		  <$view field="title"/> <!-- show title if no field is set, or specified field is empty -->
  </$transclude>
</$let>
</$link><br>
</$list>

It sounds like a use of the cascade prefix. I just discover (for your request) that we can use it with a “direct filter list” and it works.

My dummy test was

\define filterList() [search[a]then[_a_]]   [search[o]then[_O_]]   [<currentTiddler>]

{{{ cat bat bug dog :cascade[<filterList>] }}}

Your code would be something like:

\define currentTag() HelloThere
\define gSetting() $:/config/LinkTitle

\define filterList() 
[<currentTag>get[format]trim[]!match[title]]
[<gSetting>get[text]trim[]!match[title]]
[get[caption]]
[<currentTiddler>]
\end

<$list filter="[tag<currentTag>]">
<$link tooltip=<<currentTiddler>> >
<$text text={{{ [<currentTiddler>] :cascade[<filterList>] }}} />
</$link><br>
</$list>
2 Likes

@Mohammad before I spend the time going through the details of this have you considered just having a set of filters, one for each possible value and using the first?

[[ filter run 1 ]] [[ filter run 2 ]] [[ filter run 3 ]] [[ filter run 4 ]] +[first[]]

Get format [all[current]get[format]]
Get gSetting [<gSetting>]
Get format [all[current]get[caption]]
Get title [all[current]get[title]]

Resulting in the filter
[all[current]get[format]] [<gSetting>] [all[current]get[caption]] [all[current]get[title]] +[first[]]

But also note if the current tiddler is set the fields can be simplified to
[{!!format}] [<gSetting>] [{!!caption}] [{!!title}] +[first[]]

2 Likes

Thank you both (@Alvaro and @TW_Tones).
Yes, cascades and first let to choose the first result! The other part is to transclude or view field.
If field is title, just view it and for other field transclude it!

I think I have to keep the $list in the first solution in the OP.

So you also want to have it wikified after you retrieve its value?

  • If so when you display the result it will typically be wikified and this is also OK with titles unless it contains camelCase
  • You can also use the wikify widget but that is often discouraged although I have not seen any unwanted outcomes.

That is right, TW is very flexible in naming title, I like to restrict myself to some good practice! But you have titles like This is a //title//.
The first code work for me and i will stick to it!

Do as you wish, however I am confident simpler versions are possible, which seemed to be requested.

I used $text widget to simplificate your example.

I don’t know if I see your user case. Do you want this word “title” to always be displayed in italics or with the exception of when it is part of the title? Or is it other case?

Have you thinking about use $genesis widget? You could use it to select that widget you want to use with each/some condition/s. Something like the second example of its documentation.

1 Like

Thank you!

By default, title shall be displayed as you see them on tiddler, so no wikification is allowed

Not yet, but I am interested to see how it works. Specially if GensisWidget allows to modify current widget or develop new widget without JavaScript then it would be super!

If I understand you correctly, the following would work. But if i’m wrong, you only need to change the filters to match the expected results.

\define currentTag() HelloThere
\define gSetting() $:/config/LinkTitle

<$list filter="[tag<currentTag>]">
<$let theField={{{ [<currentTag>get[format]] [<gSetting>get[text]] +[trim[]!match[title]] 
[<currentTiddler>has[caption]then[caption]else[title]] +[first[]] }}} 
 theType={{{ [<theField>!match[title]then[$transclude]else[$view]] }}}>
<$link tooltip=<<currentTiddler>> >
<$genesis $type=<<theType>> field=<<theField>>/>
</$link><br>
</$let>
</$list>

I don’k know if it is the simplest.

1 Like

I am investigation :wink:

Hi @Alvaro

Thank you for your solution using GensisWidget. I revised your code and ow its working.

\define currentTag() HelloThere
\define gSetting() $:/config/LinkTitle

* Format:   <$text text={{{ [[HelloThere]get[format]] }}} />
* gSetting: <$text text={{{ [[$:/config/LinkTitle]get[text]] }}} />

<$list filter   = "[tag<currentTag>]">
<$let theField  = {{{  
                      [<currentTag>get[format]trim[]]
                      [<gSetting>get[text]trim[]]
                      [[caption]]
                      :and[first[]]
                      :map[<..currentTiddler>get<currentTiddler>then<currentTiddler>else[title]]
                  }}}
      theType={{{  [<theField>!match[title]then[$transclude]else[$view]] }}}>		
			
			-- <<theField>>
			-- <<theType>>
			
<$link tooltip=<<currentTiddler>> >
  <$genesis $type=<<theType>> field=<<theField>> />
</$link><br>
</$let>
</$list>

The logic is as below
1- determine the link title by looking into format, and then gSetting, and finally caption
2- if an item has not the field of step 1 or its field is empty then use title (as a fallback)
3- if nothing is set, use caption, if caption is empty or an item has not the caption field, then use title

1 Like