A DisplayTiddler Variable for use in multiple transclusions.

199 views
Skip to first unread message

TonyM

unread,
Nov 2, 2019, 2:17:40 AM11/2/19
to tiddl...@googlegroups.com
Folks,

A solution was found for this specific use case, before posting, but the Question still could do with an answer
  • Use the <<storyTiddler>> variable to find the "DisplayTiddler" regardless of the number of transclusions.

A reoccurring confusion of mine occurs trying to implement the following with a define rather than a set, is it possible?
<$set name="callingTiddler" value={{{ [<currentTiddler>] }}} >
1st:
<br>
{{tiddlername||Second}}
</$set>
The value <<callingTiddler>> will be available in all nested transclusions.

The problem with this is you always need to close the set widget. This means every time you edit or add something to the tiddler you have to make sure changes that need it are inside the set.

Is there a way to 
\define callingTiddler() something
to achieve the same result?

The problem is whatever you place in a macro definition gets evaluated when its displayed not before 

Of course I can use;
\define callingTiddler() actual tiddlername
With a literal tiddler name but then each tiddler needs a unique setting and you can't "import variables", make it global or any other method I can think of

Why?
  • I really want an answer to support a range of methods
  • You can see in the above the use of `{{tiddlername||Second}}`! here I can transclude Second with tiddlername acting as a parameter for "Second" to use, but I still want access to the callingTiddler in that transclusion and other nested in "Second"
I would love global a method to capture for subsequent use in transclusions the current "Display Tiddler"/callingTiddler - ie the one on the screen before transclusion, but as many of you know the currentTiddler changes according to context so it can't be used.

Note: I went looking in the tiddler $:/config/ui/ViewTemplate / $:/config/ui/ViewTemplate to see how I may set a displayTiddler value only to find the variable storyTiddler which is functionally what I need. Though it does nothing to help me define a variable that will store the current tiddler indefinitely.

Regards
Tony

Jeremy Ruston

unread,
Nov 2, 2019, 7:41:11 AM11/2/19
to tiddl...@googlegroups.com
Hi Tony

We could extend the transclude widget so that it sets a “currentTransclusionTitle” variable with the name of the tiddler that it is transcluding. We’d actually also need to set variables currentTransclusionField, currentTransclusionIndex and currentTransclusionSubtiddler to capture all the attributes of the transclusion.

Then, in your example below, the tiddler “Second” would be able to obtain the name of the tiddler from which it was transcluded.

A potential limitation is that each successive transclusion would overwrite the values of those variables. We could work around that by making the value of each variable be a list, and append the new values at each transclusion.

Does that make sense, and would it do what your after?

Finally, a small point, but you’ve got this construction:

<$set name="callingTiddler" value={{{ [<currentTiddler>] }}} >

It could be written more concisely as:

<$set name="callingTiddler" value=<<currentTiddler>>>

Best wishes

Jeremy

On 2 Nov 2019, at 06:17, TonyM <anthony...@gmail.com> wrote:

Folks,

A solution was found for this specific use case, before posting, but the Question still could do with an answer
  • Use the <<storyTiddler>> variable to find the "DisplayTiddler" regardless of the number of transclusions.

A reoccurring confusion of mine occurs trying to implement the following with a define rather than a set, is it possible?
<$set name="callingTiddler" value={{{ [<currentTiddler>] }}} >
1st:
<br>
{{tiddlername||Second}}
</$set>
The value <<callingTiddler>> will be available in all nested transclusions.

The problem with this is you always need to close the set widget. This means every time you edit or add something to the tiddler you have to make sure changes that need it are inside the set.

Is there a way to 
\define callingTiddler() something
to achieve the same result?

The problem is whatever you place in a macro definition gets evaluated when its displayed not before 

Of course I can use;
\define callingTiddler() actual tiddlername
With a literal tiddler name but then each tiddler needs a unique setting and you can't "import variables", make it global or any other method I can think of

Why?
  • I really want an answer to support a range of methods
  • You can see in the above the use of `{{tiddlername||Second}}`! here I can transclude Second with tiddlername acting as a parameter for "Second" to use, but I still want access to the callingTiddler in that transclusion and other nested in "Second"
I would love global a method to capture for subsequent use in transclusions the current "Display Tiddler"/callingTiddler - ie the one on the screen before transclusion, but as many of you know the currentTiddler changes according to context so it can't be used.

Note: I went looking in the tiddler $:/config/ui/ViewTemplate to see how I may set a displayTiddler value only to find the variable storyTiddler which is functionally what I need. Though it does nothing to help me define a variable that will store the current tiddler indefinitely.

Regards
Tony


--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/79a27e56-918e-4431-9c12-f7cc83ff3e1c%40googlegroups.com.

TonyM

unread,
Nov 2, 2019, 11:30:34 PM11/2/19
to TiddlyWiki
Jeremy,

I had not seen your reply until now. I found the heading in https://tiddlywiki.com/#Transclusion%20in%20WikiText  Generated Widgets that hinted at what you suggest. Could this be included in the use of the transclude widget as well? (not just `{{ target }}`

By the way the use of StoryTiddler variable helps me identify the equivalent of the displayTiddler in the original thread. 

I like your idea of "making the value of each variable be a list, and append the new values at each transclusion" but there is still value on setting a callingTiddler variable, that is changed with each transclusion, because it will always provide the last call, which is useful in its own right, without interrogating the list(s). This would appear in dumpvariables etc... and be somewhat diagnosticly meaningful. 

I see this may require the editing of $:/core/modules/widgets/transclude.js so I am not yet qualified to issue a change/pull request.
 
Here are some thoughts to use this development, to introduce a useful macro or widget, at the same time as the above solution is created, because the proposal requires something like this anyway. Basically exposing a common logical function to users.

To build your suggested list perhaps we can introduce a list "push and pop" widget(s) or macro and use that. Since such a push and pop could be useful elsewhere. If you are not familiar with push and pop I mean a macro or widget such as 
<<push "field/textreference" "listitem" "delimiter">>
that adds list item at the end (titles delimited Space for fields) newline for text

A default of 
<<push "field/textreference">>
would push the current tiddler title onto the end of the list in textreference


<<pop "textreference">>
Removes the last item from text reference regardless of what it is.
  • This could allow the use of recursive loops inside transclusions ie TOC equivalent. 
  • It could refuse to push a tiddler title already in the "list" to stop loops
  • It is a basic form of append, and can also be used for log solutions.

This could be used to push and pop a tag, list field entry, datatiddler items or build a branch (field) whilst iterating a TOC and more. 

Eg a recursive process could build a branch describing each tiddler by the full path to it, and save this branch/path in each tiddler, or in a data tiddler. This would allow a complex hierarchy to be saved for later, even when the source tiddlers change their relationships.

There are other possibilities that I will leave out for brevity.

Tony




On Saturday, November 2, 2019 at 10:41:11 PM UTC+11, Jeremy Ruston wrote:
Hi Tony

We could extend the transclude widget so that it sets a “currentTransclusionTitle” variable with the name of the tiddler that it is transcluding. We’d actually also need to set variables currentTransclusionField, currentTransclusionIndex and currentTransclusionSubtiddler to capture all the attributes of the transclusion.

Then, in your example below, the tiddler “Second” would be able to obtain the name of the tiddler from which it was transcluded.

A potential limitation is that each successive transclusion would overwrite the values of those variables. We could work around that by making the value of each variable be a list, and append the new values at each transclusion.

Does that make sense, and would it do what your after?

Finally, a small point, but you’ve got this construction:

<$set name="callingTiddler" value={{{ [<currentTiddler>] }}} >

It could be written more concisely as:

<$set name="callingTiddler" value=<<currentTiddler>>>

Best wishes

Jeremy

To unsubscribe from this group and stop receiving emails from it, send an email to tiddl...@googlegroups.com.

PMario

unread,
Nov 3, 2019, 9:17:37 AM11/3/19
to TiddlyWiki
Hi,

There is no need to add "push" and "pop" macros. The set-widget and TWs locale variable handling does exactly that.

Try the following code:

\define test() The tiddler knows this text

<$set name=test value="outer text">
1: <<test>><br/>
 
<$set name=test value="some inner text">
   
2: <<test>><br/>
 
</$set>
3: <<test>>
</
$set>

4: <<test>>

The \define test() ... command internally creates a "tiddler wide" test variable using the set-widget

The first set-widget defines a _new_ variable named test, that is only visible between the first <$set> and the _last_ </$set>
So at 1: test will be "outer text"

The second set-widget does the same thing. It creates a new test-variable
At 2: test will be: "some inner text"

The first </$set> closing element will "forget" the inner test-variable and activate the outer var again.
So at 3: test will be "outer text" again

The last macro call at 4: knows the "tiddler global" variable.

So the first <$set widget call is a "push" command and the first closing </$set command is a "pop" command.

The same mechanism is true for recursive code, but it's a bit more complex. ... Example will follow.

-mario

TonyM

unread,
Nov 3, 2019, 5:11:48 PM11/3/19
to TiddlyWiki
Mario

Thanks for illustrating this. I was aware of this. and we even use current Tiddler and lists with variables this way.

What was not clearly stated by me was also having access to the queue on which everything is pushed.

I don't suppose there is a way to peer into the DOM for prior values of variable name?

I realise now perhaps it must be a variable not a text reference to avoid the need for a trigger. Thus I wonder if we could use the order operators to put last, but last etc on a variable.

regards
Tony

TonyM

unread,
Nov 3, 2019, 5:27:24 PM11/3/19
to TiddlyWiki
Mario

This additional statement should maintain the tree when using nested variables.

<$set name=test-branch value={{{ [<test-branch>] [<test>] }}}

Not withstanding the above the ability to push and pop independently from nested structures, like adding tiddlers to the story list but on variables without a trigger, is still desirable.

examples

capture the full path to a tiddler while generating a toc.

Pushing values onto a stack from multiple datasets then computing the average, min max etc..

Regards
Tony

PMario

unread,
Nov 4, 2019, 8:34:53 AM11/4/19
to TiddlyWiki
On Sunday, November 3, 2019 at 11:11:48 PM UTC+1, TonyM wrote:
Mario

Thanks for illustrating this. I was aware of this. and we even use current Tiddler and lists with variables this way.

What was not clearly stated by me was also having access to the queue on which everything is pushed.


Yea, queueing can be done with recursion. ... I'll post a working "simple TOC" example, with some changes applied.

Refactoring the existing TOC and include advanced navigation is depending on the "other" navigation changes, that are in the works. .. At the moment it's in flux, since I do have new ideas every now and then, which hopefully makes all the stuff easier, even if it has more functions.

I don't suppose there is a way to peer into the DOM for prior values of variable name?


There is. I use it for debugging only. ... the li-element can get a title attribute, to show the info on hover. .. I'll add it to the example.
 

I realise now perhaps it must be a variable not a text reference to avoid the need for a trigger. Thus I wonder if we could use the order operators to put last, but last etc on a variable.


It's a relatively simple set-widget append text function.

-m

PMario

unread,
Nov 4, 2019, 9:34:53 AM11/4/19
to tiddl...@googlegroups.com
Hi,

DON'T USE IN PRODUCTION. ... THIS IS STILL EXPERIMENTAL CODE!!

Some code, that actually does a real recursion, with infinite recursion protection. If you copy paste the code below into a test-tiddler at tiddlywiki.com and tag it $:/tags/Macro you can test it with this example!


\define toc-caption() <$view field="caption"><$view field="title"/></$view>
\define getItemClass() [all[current]]-[<tv-history-list>get[current-tiddler]]

The above 2 lines are helper macros, to display "caption" (if available _and_ defined) or the "title"
getItemClass reads some history info, for advanced styling.


\define toc-body(tag,sort:"")
\whitespace trim
<ol class="tc-toc">
 
<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[enlist<visited>]""">
   
<$set name=visited filter="[enlist<visited>] [<currentTiddler>]">
     
<$set name="toc-item-class" filter=<<getItemClass>> emptyValue="toc-item-selected" value="toc-item">
       
<li class=<<toc-item-class>> title=<<visited>>>
         
<$set name="tv-wikilinks" filter="[all[current]get[toc-link]] ~yes">
           
<$link><<toc-caption>></$link>
         
</$set>
          <$macrocall $name="toc-body" tag=<<currentTiddler>> sort=<<__sort__>>/
>
       
</li>
      </
$set>
   
</$set>
  </
$list>
</ol>
\end

The above code contains the recursion and will be descussed in more detail.


\define toc(tag,sort:"",exclude)
\whitespace trim
<$set name=visited filter=<<__exclude__>> >
 
<$macrocall $name="toc-body"  tag=<<__tag__>> sort=<<__sort__>>/>
</
$set>
\end

The above code is the wrapper, that contains some initialisation functions. This macro can be activated like this:

<div class="tc-table-of-contents">
<<toc "Contents">>
</div>

The sort parameter will be _ignored_ in the whole discussion here. It's not important for the recursion function.

- The
toc() macro gets 2 important parameters: tag and exclude as
- The tag variable is passed unmodified to the toc-body()
- The important thing is, that a new variable is introduced: visited
-
<$set name=visited filter=<<__exclude__>> >

visited contains the information, which elements of the TOC have already been visited. This name hasn't been used by existing toc macros,
so there should be no naming and interpretation conflict!

visited is initialized with the "exclude" filter. This allows us, to exclude certain elements, by marking them as visisted.


--------------- toc-body in more detail ------------

toc-body(tag,sort:"") is the macro, that is called recursively.

A)
The 1st important line is the list-widget. With the very first run, the tag will be "Contents" as called in
<<toc "Contents">>

<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[enlist<visited>]""">

The filter contains 2 runs.

- The first run: [all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] will return all tiddlers tagged: Contents, excluding tiddlers in edit-mode.
- The second run: will eliminate all tiddlers, that have been already visited: -[enlist<visited>]
- With the initial call: <<toc "Contents">> the variable visited will be empty.

B)
The 2nd important line is:
<$set name=visited filter="[enlist<visited>] [<currentTiddler>]">

This line creates a new visited variable. The new value will be visited elements from A) PLUS the [<currentTiddler>] ...
This is a PUSH ... add new value to the "stack" of existing variables.

C)
The line <$set name="toc-item-class" ... is for styling only and not discussed here

D)
<li class=<<toc-item-class>> title=<<visited>> > ... for debugging. If the elements are hovered, the visited path whill be shown.

E)
<$set name="tv-wikilinks" filter="[all[current]get[toc-link]] ~yes">
<$link><<toc-caption>></$link>
</$set>


Creates the link. no fruther discussion

F)
<$macrocall $name="toc-body" tag=<<currentTiddler>> sort=<<__sort__>>/>

Calls the toc-body() macro with the "new" tag=<<currentTiddler>> ... So we can continue with A) -> recursion

IMPORTANT
</li>
</$set>
</$set>
</$list>
</ol>

Those elements are NOT executed yet, since the "program" jumps recursively into toc-body(), as long as new tagged elements are found.

If no new elements are fund it starts executing the close commands eg: </$set>, which is a POP command for 1 visited variable, that has been created.

I hope this helps a little bit better, since it is using a "real world" example.

The visited variable is the "infinite recursion protection".

A "path" variable will be needed for the expandable stuff. path is different to visited.

have fun!
mario

PMario

unread,
Nov 4, 2019, 9:44:20 AM11/4/19
to TiddlyWiki
On Sunday, November 3, 2019 at 11:27:24 PM UTC+1, TonyM wrote:
 
This additional statement should maintain the tree when using nested variables.

<$set name=test-branch value={{{ [<test-branch>]  [<test>] }}}


That's right. ... In my example I use visited, with a different code, but does the same thing.

-m

Jeremy Ruston

unread,
Nov 4, 2019, 1:33:09 PM11/4/19
to TiddlyWiki
Hi Tony

I had not seen your reply until now. I found the heading in https://tiddlywiki.com/#Transclusion%20in%20WikiText  Generated Widgets that hinted at what you suggest. Could this be included in the use of the transclude widget as well? (not just `{{ target }}`

Yes; the {{}} syntax is a shortcut for writing <$tiddler>/<$transclude>.


By the way the use of StoryTiddler variable helps me identify the equivalent of the displayTiddler in the original thread. 

Right, that’s a bit easier, we already set that in the story river.

I like your idea of "making the value of each variable be a list, and append the new values at each transclusion" but there is still value on setting a callingTiddler variable, that is changed with each transclusion, because it will always provide the last call, which is useful in its own right, without interrogating the list(s). This would appear in dumpvariables etc... and be somewhat diagnosticly meaningful. 

OK, I think you’re saying that you’d prefer to have each item available as both a single value, and a list/stack of accumulated values.

Here are some thoughts to use this development, to introduce a useful macro or widget, at the same time as the above solution is created, because the proposal requires something like this anyway. Basically exposing a common logical function to users.

As discussed by others, we already have the ability to perform push/pop operations.

Best wishes

Jeremy

To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/130819b8-a9b2-49ca-980e-2252b761714f%40googlegroups.com.

TonyM

unread,
Nov 4, 2019, 6:09:35 PM11/4/19
to TiddlyWiki
Mario,

I will review your demos at my soonest possible opportunity. Thanks for your effort.

Jeremy,

I understand We have a push pop available to us almost incidently within nested structures,through the redefinition of a variable. I would still like to see an independent push pop that does not depend on nesting. But I expect I may be able to build one, but for a small gap I still perceive. We do not seem to have a global variable that can be changed or used as an accumulator globaly without a trigger involved, to change a text reference.

I will keep working on it.

Regards
Tony

PMario

unread,
Nov 5, 2019, 5:12:12 AM11/5/19
to tiddl...@googlegroups.com
On Sunday, November 3, 2019 at 11:27:24 PM UTC+1, TonyM wrote:
...
capture the full path to a tiddler while generating a toc.

This should be done using nested variables. There are several advantages that come with it. 

Pushing values onto a stack from multiple datasets then computing the average, min max etc..


I think, that's an argument. ... So "the stack" can be created once and used several times. ...

Some _pseudo code_ may look like:

\define stack-1()

<$list filter="[tag[test]]">
<$push name="stack-1" value={{!!value}}/>
</$list>

{{{[<stack-1>] +[sum[]]}}}

{{{[<stack-1>] +[maxall[]]}}}

<$clear name="statck-1"/>

or something like this.

PMario

unread,
Nov 5, 2019, 5:20:58 AM11/5/19
to TiddlyWiki
On Tuesday, November 5, 2019 at 11:12:12 AM UTC+1, PMario wrote:
...
Some _pseudo code_ may look like:

\define stack-1()

<$list filter="[tag[test]]">

BUT if we add eg: 
<$set name="stack-1" ...

<$push name="stack-1" value={{!!value}}/>
</$list>

I think, we are doomed!

-m

PMario

unread,
Nov 5, 2019, 5:25:43 AM11/5/19
to TiddlyWiki
May be stacks must be all uppercase eg: STACK-1 so we can check and see, there is something special going on.

I think, the name stack is somewhat misleading, since we can do: [enlist[STACK-1]nth[3]] or stuff like this, which is "array handling"

-m


Jeremy Ruston

unread,
Nov 5, 2019, 5:58:37 AM11/5/19
to TiddlyWiki
Hi Mario

I’m not sure I’m following all of this thread, but it looks like you’re wanting variables to work fundamentally differently than they do at the moment. Some of your examples require lateral variables, which is to say variable values that are inherited by widgets from their older siblings instead of just from their parents. That’s a big change, and requires the refresh mechanism to be redesigned, but it’s one I’m interested in for TWX because it’s the only way we’ll be able to do things like autonumbering of footnotes.

Best wishes

Jeremy

-- 
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/75d370dd-8721-445c-88ac-981897a3c1ec%40googlegroups.com.

TonyM

unread,
Nov 5, 2019, 6:13:30 AM11/5/19
to TiddlyWiki
Jeremy

Is the following an example of a lateral variable?

\define varvalue() {{tiddlername}}
on close tiddler I have an action that adds 1 to <<varvalue>> and saves it back to tiddlername and sets a current tiddler field to the same value.

This is how I get unique serial numbers for tiddlers.

This is ok because I can use the close button as the trigger.

If there were a way to change the value in tiddlername without a trigger do I not have a lateral variable?

regards
Tony

Jeremy Ruston

unread,
Nov 5, 2019, 6:16:20 AM11/5/19
to TiddlyWiki
> Is the following an example of a lateral variable?

No, that’s just using a variable to update the value in a tiddler. It’s a perfectly useful technique.

> If there were a way to change the value in tiddlername without a trigger do I not have a lateral variable?

No. For a tiddler value to change, there has to be a trigger.

Hence the need for lateral variables.

Best wishes

Jeremy



>
> regards
> Tony
>
> --
> You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/60fa391a-262e-407b-8952-7981d2fa1419%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages