How to use the transclude widget and shorthand transcludes

Folks,

[Edit] I have Renamed this thread as its a valuable resource and will split out the discussion on futures

I am deep in other research and want to clarify if my understanding of the following is true; If correct it may help document this for those finding the shorthand transclusions insufficient.

I have long felt there is a slight gap in my understanding of the transition from shorthand transclusions to the widget form.

Imagine the currentTiddler variable is set, then we have;

<$transclude/>

My understanding is the above will transclude the currentTiddler - but effectively just its text field. This is then rendered.

  • Is this equivalent to {{currentTiddler}}?

Again if the currentTiddler is set and we have;

<$transclude tiddler=othertiddler />

My understanding is the above will transclude the currentTiddler - but it will do this using the “template” othertiddler. Thus equivalent to {{||othertiddler}} with currentTiddler assumed.

Then in the following case;

<$tiddler tiddler=subjectTiddler>
    <$transclude tiddler=othertiddler />
</$tiddler>

I understand this to be the equivalent of {{subjectTiddler||othertiddler}}

We may also note;

The TranscludeWidget treats any contained content as a fallback if the target of the transclusion is not defined (ie a missing tiddler or a missing field).

Thus if we had the following;

<$tiddler tiddler=subjectTiddler>
    <$transclude tiddler=othertiddler>
         yetanothertiddler
   </$transclude>
</$tiddler>

Then I understand if “othertiddler” did not exist “yetanothertiddler” would be used as the template.

That is the equivalent of {{subjectTiddler||yetanothertiddler}} is and only if “othertiddler” does not exist and/or has an empty text field.

Questions;

  1. Are my observations correct?
  2. If so then, is a little misleading that its tiddler=othertiddler rather than template=othertiddler?
  3. Given the above, what will happen in the following case; <$transclude tiddler=othertiddler field=fieldname/> ?
    3.1 and / or it does not contain anything in the fieldname?
    3.2 what is the short hand versions of this

Thanks in advance! (1am here - good night)

“yetanothertiddler” is treated as wikitext, not a reference to another tiddler. I’m not quite sure you are saying otherwise. I just wanted to clarify, just in case.

To see what I mean, try this on tiddlywiki.com:

<$transclude tiddler="non-existing-tiddler">
Hi, I'm just __wikitext__
</$transclude>

Naming the attribute tiddler makes sense to me.

The purpose of the transclude widget is to parse and render the contents of the given field (default=text) and given tiddler (default=<<currentTiddler>>). If the contents of that tiddler/field combination happen to be wikitext and that wikitext contains “relative” references (i.e. {{!!myfield}} or {{!!title}} or <<currentTiddler>>, etc.), then it will operate as a template.

If the contents are not wikitext or it is wikitext without any “relative” reference, then no template behavior will be seen. In that case it might be misleading to name the attribute template. This is just the way TW parsing and rendering works. The TranscludeWidget has no special knowledge about whether a tiddler will have template qualities or not.

Try these examples on tiddlywiki.com. The contents of the given tiddler/field are parsed and rendered. If nothing is there in the the field, then the result will be blank.

`<$transclude tiddler=TextWidget field=caption/>` = 
<$transclude tiddler=TextWidget field=caption/>

`<$transclude tiddler=TextWidget field="non-existing-field"/>` = 
<$transclude tiddler=TextWidget field="non-existing-field"/>

The shorthand for this is {{TextWidget!!caption}}

Or maybe you are asking for the shorthand for something like the following (which doesn’t do anything useful because the caption field of the TextWidget doesn’t have any relative references to give it template features):

<$tiddler tiddler="About">
<$transclude tiddler=TextWidget field=caption/>
</$tiddler>

I didn’t check the code, but things like {{About||TextWidget!!caption}} didn’t work. I think the only shorthand you would get for this is:

<$tiddler tiddler="About">
{{TextWidget!!caption}}
</$tiddler>

But again, in this particular example, the wrapping tiddler widget has no effect because The TextWidget caption doesn’t have anything to give it useful template behavior.


Edit to add:

These are better examples and shows that my last example is not equivalent shorthand:

<$tiddler tiddler=Transclusion>
  <$transclude tiddler="$:/core/ui/TagTemplate" field="text"/>
</$tiddler>

<$tiddler tiddler=Transclusion>  
  {{$:/core/ui/TagTemplate!!text}}
</$tiddler>

<$tiddler tiddler=Transclusion>  
  {{||$:/core/ui/TagTemplate!!text}}
</$tiddler>

I’m explicitly mentioning the field as text even though it is the default so we can see useful behavior without changing any tiddlers. The first two above are not equivalent. The last one is not supported as shorthand. The full widget syntax must be used instead.

2 Likes

David, Thanks so much for your comprehensive answer to my issue. You have lifted the shatters over my eyes as I clearly had the knowledge to understand this but was experiencing some kind of blog.

I plan to compose a new summary of this and post a new topic “How to use transclusion”, It will be a wiki page so feel free to contribute.

FYI: I believe the following should have read;

<$tiddler tiddler=subjectTiddler>
    <$transclude tiddler=othertiddler>
         {{||yetanothertiddler}}
   </$transclude>
</$tiddler>

to match my language.

I found your statements about

and

Actually I understand what you mean here, it helped me understand, however I now see it is slightly wrong.

Relative references typically mean the “transclusion” continues further. But it is not needed for the template. A transclusion can just be simple text after all.

I now see the transclusion widget works the same as the list widget, if it has no template parameter then the content is the template.

By the way the <<transclusion>> variable helps identify the details, put it in a caption you are transcluding.

<$list filter="filter">
this is the template
</$list>
<$transclude tiddler=missing>
this is the template if no tiddler given, but can itself contain a transclusion. {{test}}
</$transclude>
  • Note: If not tiddler=missing is NOT provided, transclude transcludes the current tiddler giving Recursive transclusion error in transclude widget

But;

<$transclude tiddler=tiddlername/>

“Transcludes” the tiddlername

I now realise the transclude widget is always applying a “template” be it a named tiddler or field or both, or inline content.

However when one tiddler ONLY transcludes another tiddler (ie the current tiddler has no text content, but may have other fields) then it really is a template because we can ONLY see the content current tiddler through the template tiddler. Ie the text field of one tiddler becomes that of the currentTiddler.

So my take home is when we say <$transclude tiddler=tiddlername/> tiddler name is the “template”, and that is what transcluding is and if not available it resorts to the content of the transclude (in this case nothing).

So I do still think we could have an alias for the tiddler parameter of template and it would read much better, especially for new users.
<$transclude template=tiddlername/> there by implying it is a template (only) and applied to the current tiddler, as it is.

Thanks again - you really have helped. :pray:

Wow, does that ever suck.

I thought <$transclude tiddler="This Tiddler"/> did the same as {{This Tiddler}}.

The documentation is definitely not clear, and I think the widget is seriously flawed.

In my mind, <$transclude tiddler="This Tiddler"/> and {{This Tiddler}} ought to work exactly the same.

And, the transclude widget ought to have a template attribute such that <$transclude tiddler="This Tiddler" template="This Template/> and {{This Tiddler || This Template}}ought to work the same.

Just to add, the definition of TranscludeWidget:

The TranscludeWidget dynamically imports content from another tiddler.

From Wikipedia:

In computer science, transclusion is the inclusion of part or all of an electronic document into one or more other documents by hypertext reference.

1 Like

@TW_Tones

Have you tried this?

<$tiddler tiddler=subjectTiddler>
	<$transclude  field=summary>
		<$transclude  field=caption>
			<$transclude  field=title/>
		</$transclude>
	</$transclude>
</$tiddler>

It looks for summary, if not present THEN looks for caption, if not exist, THEN shows the title!

You are allowed to have an infinite nesting!
I call this Nested Transclusion!

See conditional output in TW-Scripts!

1 Like

Please kindly do this! $transclude widget is among the most powerful widgets in Tiddlywiki which has not gotten enough attention!

2 Likes

@TW_Tones
It may be funny, I had a guard against currentTiddler for quite long time and submitted issues, ideas or sent serval posts and questions in GG, asking to change the name of default variable in $list widget!

When I realized how to use transclusion, I understood how important is currentTiddler and why it is called currentTiddler :sweat_smile:

So, if you want to start a writeup about Transclusion widget! do not forget to discuss currentTiddler

1 Like

It could have had any other name. … As so many defaults in TW the name currentTiddler is “just” a convention. A convention used all over the places in the TW wikitext and also the core javascript code. …

So as it is now, it can’t be changed without breaking stuff. Therefore it’s a standard.

Jeremy sometimes needed to use “strange” names that are still self explaining and won’t clash with user-names for variables.

It is very likely, that current or default would have clashed with “simpler” variables, that users want to use.

Similar names are eg: $:/tags/Stylesheet … Users are free to use “Stylesheet” to create a “category tag”, without clashing with the system and causing side effects.

See the new variable names in eg: the https://tiddlywiki.com/#KeyboardWidget … They are named: event-key … event-code and so on. So the variables key and code are still open to be used by users.

Defining names, that are used by the system AND stay out of the users way is hard. There are pages and pages of discussions on GitHub, just to find a good names …

Variables used by the core functions also need to be chosen in a way that allows future development. In the future it has to be “backwards compatible”. … It’s like “time travelling” … So strange things can happen :wink:

1 Like

I do this for my own naming, basicaly qualify common names by there application, scope or context. However especialy in my own solutions i also aim for the shortest meaningful names. But tiddlywiki is quite tollerent providing its own context like inside a macro or view template, or transclusion.

In many cases it will do the same thing. Try it on tiddlywiki.com with this in a new tiddler (puts the two transclusions a table row so they can be seen side-by-side):

|{{About}}|<$transclude tiddler="About"/>|

For this particular About tiddler, it will render identically, but that won’t be the case for all tiddlers.

The parse results are not the same as each other, but in the end, they render the same. This is because the About tiddler doesn’t contain any “relative” field references (be they nested relative transclusions as Tony mentioned, or field reference by some other widget). The “$:/core/ui/TagTemplate” does have “relative” field references and therefore, the following two examples render different from each other:

|{{$:/core/ui/TagTemplate}}|<$transclude tiddler="$:/core/ui/TagTemplate"/>|

TW has a marvelous widget called wikify which can be used to expose some of tiddlywiki’s internal working. One output format of this widget will show the parsetree of some wikitext. If two parse trees are identical (or functionally identical, unfortunately it isn’t completely straightforward), then the rendering will be identical.

I played around with some wikify markup using the parsetree output format [1] and discovered the following.

These 3 constructs yield effectively identical parse trees (the first two are character-for-character identical, the third one differs in ways that don’t impact the rendering):

  1. {{About}}
  2. {{About||About}}
  3. <$tiddler tiddler="About"><$transclude tiddler="About"/></$tiddler>

These two give functionally the same parsetree as each other:

  1. {{||About}}
  2. <$transclude tiddler="About"/>

These two also give functionally the same parsetree as each other:

  1. {{About||$:/core/ui/TagTemplate}}
  2. <$tiddler tiddler=About><$transclude tiddler="$:/core/ui/TagTemplate"/></$tiddler>

[1] Here is the tiddler contents I used to make the above conclusions (I use a table so the results can be viewed side-by-side and due to that it requires a wide screen):

\define parsetree(text)
<$wikify name=result text=<<__text__>> output=parsetree mode=inline>
  <pre>
  <$text text=<<__text__>> />
  </pre>
  parses as:
  <pre>
    <<result>>
  </pre>
</$wikify>
\end

|<<parsetree "{{About}}">>|<<parsetree "{{About||About}}">>|<<parsetree """<$tiddler tiddler="About"><$transclude tiddler="About"/></$tiddler>""">>|

|<<parsetree "{{||About}}">>|<<parsetree """<$transclude tiddler="About"/>""">>|

|<<parsetree "{{About||$:/core/ui/TagTemplate}}">>|<<parsetree """<$tiddler tiddler=About><$transclude tiddler="$:/core/ui/TagTemplate"/></$tiddler>""">>|

And also this one

<$vars currentTiddler=About>
<$transclude tiddler="$:/core/ui/TagTemplate"/>
</$vars>

The main point in all these is to which object the currentTiddler refers!
This is like self or me in object oriented paradigm!

I had a wiki on Tiddlywiki and OOP, but I cannot find it now! I think using transclusion it is not difficult to have doe features of OOP!

Write the below script in a new tiddler in https://tiddlywiki.com/

<$list filter="[tag[About]]">
{{||$:/core/ui/Buttons/delete}} - <$link/><br>
</$list>

you get this!

So, each of these like a class and if you pass the right object (a tiddler is a loose object) then you can see how much flexibility you have in Tiddlywiki!

In my opinion Tiddlywiki is very flexible and transclusion is like a magic!
but as much as Tiddlywiki itself is great, amazing and powerful! its documentation is terrible and confusing! You have to just learn through practice and Q&A in forum! Fortunately there are lovely TW fans/users which help you and if you ask a question you get several right answers :grinning:

So, I believe, if only the concept of transclusion demystified, even non technical users can create sophisticated tools! because TW with transclusion is like LEGO! there are many shapes out there and just you should start to build your own app, no programming skills are needed!

3 Likes

Good point. These are two synonymous ways of setting currentTiddler:

  1. <$vars currentTiddler=About/>
  2. <$tiddler tiddler=About/>

and there are other ways as well.

====== split here ========

Yes and if nboting else I think users need to recognise this parameter “tiddler” is NOT setting the currentTiddler variable;

<$tranclude tiddler="tiddlername"/>

Yet this parameter “tiddler” is setting the tiddlername to be used as the template;

This is why I think it could be helpful in the long run if we have a synonym for this parameter so that;

<$tranclude template="tiddlername"/>

The above would mean the same thing!

1 Like

Adding “template” as a synonym of “tiddler” for the transclude widget is the way to go. Newer code would be clearer and old one would keep functioning.

After a while, “tiddler” could disappear (obsolescence) for it should not have been name thus as it was not immediately clear that the transclude widget was only about providing a template.

I was confused about it today and read this thread that was very helpful indeed!

When you read the official doc, the transclude widget is meant to transclude text. It does not even talk about template.

Something is wrong and IMHO sould be fixed. Several ways could be for this. So how to write {{fu||bar}} with widget?

  • add a template widget that would transclude with a template (default to current tiddler) and have transclude not having template abilities of itself. <$template template=bar><$transclude tiddler=fu/></$template>
  • add a template widget that would also transclude by himself. <$template template=bar tiddler=fu/>
  • deprecate the tiddler parameter of the transclude widget and instead use two new parameters: source and tremplate. <$transclude template=bar source=fu/>
  • simply add the template synonym to the current transclude widget but also refuse to act if both tiddler and template are used in the same widget as that would mean the author is wrong. <$tiddler tiddler=fu><$template template=bar/></$tiddler>

That’s a good suggestion.

The transclude widget does transclude text. The templating features only come into play if the text contains widgets referencing the current tiddler variable. Templating is built on transclusion, but transclusion isn’t the only thing that templating rests on.

I’m not sure what’s wrong here. The official docs cover the relationship between the {{fu||bar}} syntax and the underlying widgets that are generated.