There is no emptyValue for the view widget

Hello all

I’m not sure if this is an area for possible improvement or not, but it appears to work under the principle of " The content of the <$view> widget is displayed if the field or property is missing or empty."

<ul>
<$list filter="[tag<currentTiddler>sort[date]]" >
<li><$view field="date" format="date" template="[UTC]YYYY.0MM.0DD">0000.00.00</$view>  - <$link to={{!!title}}><$view field="headline">
</$link></li>
</$list></ul>

Is there a reason it is not possible to set an emptyValue for the view widget? It seems it would be more intuitive than my solution above.

Arguably emptyMessage may be better like the list widget. Or perhaps it makes sence the way it is because other widgets follow the same patten. Yet there is nothing like having all the parameters available.

The $view widget is pretty old code and potentially on the list of things that might be deprecated and rewritten one day. It has in most respects been superseded by newer and more versatile techniques that use filters. Extending and using the filter language is not only more powerful but helps avoid duplication of code and affordances at the widget level. So as an alternative you might do something like this for your use case:

<$let date-template="[UTC]YYYY.0MM.0DD">
<ul>
<$list filter="[tag<currentTiddler>sort[date]]" >
<li><$text text={{{ [<currentTiddler>get[date]format:date<date-template>] :else[[0000.00.00]] }}}/>  - <$link to={{!!title}}><$text text={{!!headline}}>
</$link></li>
</$list></ul>
</$let>
3 Likes

In situations where one needs to pass a block of wikitext to a widget, the preferred technique is for the wikitext to be contained within the widget. That is why you’ll find the pattern with widgets like view and transclude.

The list widget needs to take two blocks of wikitext, but it can only contain a single block. Hence why we added the emptyMessage attribute.

The problem with passing wikitext within an attribute is that the wikitext has to be entirely reparsed and rerendered whenever the attribute text changes. In contrast, wikitext contained within the widget will just be parsed once, at the same time as the widget.

It’s worth noting that the other way we could have approached the list widget would be to have used subwidgets to identify the different wikitext blocks that we want to pass:

<$list filter="...">
  <$template>
    This is an entry <$text text=<<currentTiddler>>/>
  </$template>
  <$empty>
    The list is empty!
  </$empty>
</$list>

This subwidget idea if it was available would be helpful for if then else or case structures especialy to allow nesting. Some code structures may be more efficent with such a method, as now we often gave a second opposite/negated condition.

thanks all for the feedback. hopefully my phrasing of the question might be of use to someone else if they are searching for the same solution.

Before this subject is totally forgotten remember that;

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

see https://tiddlywiki.com/#ViewWidget

Try this on tiddlywiki.com

<$view field=modified format="relativedate"/>

<$view field=anotherdate format="relativedate">
   emptyMessage
</$view>

In the above since there is no anotherdate instead the the emptyMessage text is displayed.

@jeremyruston for ideas re if/else/nesting and see my next reply for subwidget idea.

So rather than introduce sub widgets consider this;

  • It should not overload the list widget because it is just a parameter and setting the template.

Thus;
If we consider the list widget, which has a few ways to specify the template to be used.

Current Examples of the list widget;

<$list filter="[tag[Lists]sort[title]]"/>
<hr>
<$list filter="[tag[Lists]sort[title]]"><<currentTiddler>>, </$list>.
<hr>
<$list filter="[tag[Lists]sort[title]]">

</$list>
<hr>
<$list filter="[tag[Lists]sort[title]]">
  Not empty
</$list>
<hr>
<$list filter="[tag[Lists]sort[title]]" template="$:/core/ui/ListItemTemplate">
   Does not appear if the template is used
   Perhaps this could be used as the emptyMessage template if emptyMessage parameter is not provided but template it.
</$list>
<hr>

above Works on tiddlywiki.com

Slight change to the list widget.

Consider then if the List widget included a message= parameter as a complement to the emptyMessage= parameter.

<$list filter="filter" message=<<eachitem>> emptyMessage=<<no items>>/>

However if one of the two parameters are missing then the content of the list widget acts as the template for that.

<$list filter="filter" message=<<eachitem>>  >
<<no items>>
</$list>

Or

<$list filter="filter" emptyMessage=<<no items>>  >
<<eachitem>>
</$list>

In the above if “message” is not provided the behaviour is not different so this should be backward compatible.

Why?

This would make it very easy to “Nest list widgets” by choosing if the body is the true/false or message/emptyMessage condition. Especially when you want a default action or to handle the “nul” or else case".

For example consider this nest or “case” structure that would be possible.

<$list filter="one two three +[match<my-variable>]]" variable=result>
   <$list filter="[<result>match[one]]" message=<<doifone>> >
      <$list filter="[<result>match[two]]" message=<<doiftwo>> >
          <$list filter="[<result>match[three]]" message=<<doifthree>> >
               No valid `result` eg: please provide the my-variable
           </$list>
        </$list>
     </$list>
</$list>

Fore Message and emptyMessage we could use the parameters if and else.

If you consider the example in my last reply but allow message and emptyMessage parameter’s to specify a subwidget name as if it were a macro.

I hope this is helpful @jeremyruston.

Here I will use if and else parameters rather than message and emptyMessage. Just to illustrate an alternative.

<$list filter="one two three +[match<my-variable>]]" if=<<hasvalue>> else=<<novalue>>  variable=result>

   <hasvalue>
       template for has (each or any) value with valid `<<result>>`
   </hasvalue>

   <novalue>
       template for no value with nul `<<result>>`
   </novalue>
</$list>

What is interesting about this approach the contents of the sub widgets can internally, effectively just be turned into a variable to use as the template.

  • basically it allows the “variables” to be defined inline as wikitext which is desirable so we are not forced to code macros elsewhere and the code can be read in one place.
  • It now looks a bit more like other programming languages.
  • Arguably the sub widgets definition could exist outside the list widget as well for reusable sub widgets.
    • We already have the \define macroname() for this already but we can not define something inline, They must also appear at the top of the tiddler.
    • We could use set, vars and let which needs to be outside and wrapp the current widget (open/close).
    • Not coding inline is not always helpful when trying to write self documenting code.

This is also discussed here