Nested widgets what is this called

@EricShulman ‘s response to an earlier query. Regarding the display of captions instead of titles raised something that has been on my mind for some time. His example of a view widget inside a transclusion widget in an ingenious way to have a if..then condition.

so, what is this called? What do I look up to learn about it?

In particular, what widgets support this, how many levels of Nesting are supported?

Bobj

There are many widgets that use their contents as a normal part of their operation. For example:

  • $let, $vars, $set and $wikify each define variables that are then available for reference within their content
  • $list evaluates a filter and renders content for each matching tiddler
  • $action-confirm displays an “ok/cancel” message and, if “ok” is clicked, performs whatever action widgets are within it contents
  • etc.

There are also some widgets that completely ignore their contents, such as $text, $edit-text, $count, $browse, and most (but not all) $action- widgets.

However, there are very few widgets that use their content for “fallback” handling. These include: $transclude and $view (as previously noted), and also $macrocall (which SAYS it’s contents are ignored, but actually works as a fallback if the $name=... parameter references a non-existent macro). There may be other widgets that do this as well, but the documentation on this is spotty at best.

-e

Long story short: If a widget by default is “self closing”. So by default it has no body. It’s called a fallback body


Long story :wink:

As Eric pointed out for many widgets it’s common to have a “content”. The area between widget start-marker and the end-marker is also called body. eg: $let

The let-widget always “renders” it’s body.

<$let test-a="abc">
  <<test-a>>
</$let>

Some widgets have a “fallback” value that is used, if a filter or a variable is empty. eg: list-widget. The emptyMessage parameter is used if the list-widget filter produces no result. eg:

<$list filter="[tag[non-existant]]" emptyMessage="n/a">
  <$link/>
</$list>

So the emptyMessage contains a so called fallback value

Some widgets by default “ignore” their body. $view and $transclude, because they have parameters, that are used to show the content of something. $view and $transclude have a tiddler-parameter. Those widgets by default are self closing. They have /> at the end. They have no body. eg:

<$transclude $tiddler="non-existant"/>

Since the “non-existant” tiddler does not exist this transclusion would show nothing. Which may or may not be what a user wants. If we always need “output” there needs to be a mechanism allows us to do so. That’s the “fallback body”.

This fallback body is “prominently” used with the caption field in lists and the TOC macros. Which does this:

\define toc-caption()
\whitespace trim
<span class="tc-toc-caption tc-tiny-gap-left">
<$set name="tv-wikilinks" value="no">
  <$transclude field="caption">
    <$view field="title"/>
  </$transclude>
</$set>
</span>
\end

By default the transclusion does not show anything, if it’s parameter does not exist. So if there is no caption-field, it would be empty. Since we do not want that, the transclusion widget uses a fallback body. …

It shows the title instead. Since the title field is the only field a tidder must have we can be sure there is something. Even if it is $:/very/long/title/like/this. May be not what we want to see, but at least there is something.

This mechanism is also used by the tabs-macro and probably many other places.

Hope that makes sense
-mario

Perfect sense @pmario , thank you for taking the time to explain.

One question though , can such a fallback facility be nested, ie. can the fallback widget itself have a fallback widget?

Bobj

Yes. For example, suppose you have a custom field named alt-title, you could write something like this:

<$transclude field="alt-title">
  <$transclude field="caption">
    <$view field="title"/>
  </$transclude>
</$transclude>

This would let you have an alt-title that supersedes the caption, with a final fallback to title if neither an alt-title nor caption are defined.

-e

Great @EricShulman thanks for the clarification, by you both. Be nice to have this in the documentation but I guess that’ll not happen unless it is and I haven’t come across it.

bobj

other related fall backs are;

  • aforementioned emptyMessage
  • aforementioned The content of the <$view> widget is displayed if the field or property is missing or empty.
    • searching for “The content of” reveals how this works in other widgets
  • if using the $fill and $slot widgets mention is made of " The TranscludeWidget uses the special slot ts-missing to specify the content to be rendered if the transclusion target is not defined (i.e. a missing tiddler or a missing field).
  • The empty $list widget
  • Even the $link widget has a degree of fall back behaviour you may otherwise think of as defaults.

We can also mention the fact that if we transclude a transclusion, transclusion “attempts to wikify” the transclusion, and one part of wikification is transclusion, and this will keep occurring to an arbitrary depth.

  • This means you could end up transcluding the first transclusion and end up in an infinite loop. There is some protection built in for such cases, but is wise to avoid such cases which can result in infinite loops.
  • But judicious use can provide a very powerful design pattern, and helps you reuse code or content effectively only ever having one copy, and this is effectively used by many including the core.
  • Keep in mind your macros and procedures could contain transclusions, or items with a fall back and be the cause of a loop.
  • If you find you need to use the $wikify widget you may be better using a transclusion or even a function to cause evaluation of underlying wiki text or TiddlyWiki script or filters to occur before the final render.

How tiddlywiki may differ from other code environments

Functions being evaluated

The best thing about functions, or triple curly braces and the new back tick attributes is they are evaluated “in place” so their wikification is unnecessary.