Program flow: how to store a variable in a field without user intervention?

332 views
Skip to first unread message

bimlas

unread,
Jan 4, 2019, 5:20:42 AM1/4/19
to TiddlyWiki
The basic structure of TiddlyWiki is XML, and it also feels because everything is embedded in one another.

```
In the list of tiddlers
   If tiddler meets a condition
     List its tags
   end
end
```

There are program flows that cannot be implemented in it, such as defining a variable in one block, which is evaluated in another block.

```
In the list of tiddlers
   If tiddler meets a condition
     Add its tags to a list of tags
   end
end

Filter out duplications from the list of tags
Show the list of tags
```

In principle, we could use fields of tiddlers to store variables, but we can only modify them by direct user intervention (eg. `<$action-listops` by pressing a button).

How do I implement the second example without user intervention?

TonyM

unread,
Jan 4, 2019, 5:46:42 AM1/4/19
to TiddlyWiki
Bimlas,

How I understand it

Since many changes in tiddlywiki result in a need to update all relevant tiddlers (using the widget tree) there are few if any ways to make something happen without a trigger. If there were it may be possible to trigger triggers and end up with endless loops etc... For this reason you need to trigger such actions.

This is not as problematic as it would first seem, because inside a trigger such as a button, you can perform a lot of actions, including setting multiple values across multiple tiddlers by means such as placing a list widget inside the button.

You can also leverage the navigation mechanisium or existing buttons such as close to perform / trigger an action on a tiddler, as it is closed.

In your 2nd example above, a Tag is in fact a way to list multiple tiddlers, So you can just tag any tiddler that meets a particular condition with "your list of tags" tag. Then where ever you want to see all the tags of the selected tiddlers meeting that condition you can list them in real time (tags of all tiddlers so tagged) . But of course you want this " tag any tiddler that meets a particular condition" to occur without user intervention, so you need to leverage another trigger.

Does this help?

Tony

bimlas

unread,
Jan 4, 2019, 6:28:35 AM1/4/19
to TiddlyWiki
TonyM,

Okay, I'll explain the problem more clearly:

I would like to write a TableOfContents macro, where the related tags are listed alongside the list items itself.


vivaldi_2019-01-04_12-00-41.png


You can use the list of related tags to narrow the list of tiddlers (for example, list only those that are linked to Negatable Operators and Tag Operators).

vivaldi_2019-01-04_12-07-22.png


The current solution works, but it is very slow, because going down the ToC level, it is narrowing down the list of tiddlers from level to level (`kin::to[Reference]kin::to[Concepts]...`). Instead, I reverse the logic: only one of the tiddlers associated with the lowest-level tag is listed, which is associated with each of the upstream levels (each of `tag[Tag operators]` where all of the upstream tags applies to `kin::from<currentTiddler>`).

Since this is a time-consuming operation, I only want to collect the list once, but I have to use it in two places: listing the related tags and listing the tiddlers themselves. So the logic would be exactly that:

```
In the list of tiddlers of current "lowest" tag
   If tiddler fits to each of the "higher" tags
     Add the tiddler to a tiddler list
   end
end
List the related tags of tiddler list
List the tiddler list itself
```

Since it's a table of contents, I should not change the tiddlers of the list to make them easier to parse (adding some temporary tags). A button + <$action-listops is not appropriate because when the user first opens the page, no button is pressed, so triggers are not executed.

I think the beginning of the macro should analyze what the current context is, collect the tiddlers and store them somehow. That's what I got stuck with.

TonyM

unread,
Jan 4, 2019, 7:06:49 AM1/4/19
to TiddlyWiki
Bimlas,

I will look in more detail later, but remember if you have a macro that generates a list of titles you can use that macro in a widget or other macro to act on the members of that list.

I know its a quick tip only but may get you there.

Tony

Xavier Cazin

unread,
Jan 4, 2019, 1:13:29 PM1/4/19
to tiddl...@googlegroups.com
Hi bimlas,

FWIW, the event of loading the wiki  is one of the possible triggers for
actions : https://tiddlywiki.com/#StartupActions

Xavier.

--
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 post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/a83417bb-6080-470d-be18-eeaac931c8f3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brian Theado

unread,
Jan 4, 2019, 6:04:36 PM1/4/19
to tiddl...@googlegroups.com
bimlas,

I'm not sure I understand what you mean, but here is my guess. I store the results of a filter in a variable and use that variable in two different places:

<$set name="mylist" filter="[tag[Filter Operators]]">
   List the related tags of tiddler list
  <$list filter="[enlist<mylist>tags[]]">
    <li><<currentTiddler>></li>
  </$list>

  List the tiddler list itself
  <$list filter="[enlist<mylist>]">
    <li><<currentTiddler>></li>
  </$list>
</$set>

Is that what you are looking for?

Brian

--

TonyM

unread,
Jan 4, 2019, 6:40:16 PM1/4/19
to TiddlyWiki
Erics answer in this thread will help towards this https://groups.google.com/forum/#!topic/tiddlywiki/oMBoAkJIZhQ

Whilst it includes batch manipulation by button press it shows the action widgets inside a list widget to apply to multiple. Place the logic there in the actions of what ever trigger you decide.

I have being pressing for the ability to action on tiddler open for some time, however there are real issues to be addressed. Not least of all is questioning why you would want this automatic?, how many times do you wish to do this?

Regards
Tony





On Friday, 4 January 2019 21:20:42 UTC+11, bimlas wrote:

Mohammad

unread,
Jan 4, 2019, 10:03:17 PM1/4/19
to TiddlyWiki
Brian,
Does enlist work with title have space?

Mohammad

Brian Theado

unread,
Jan 4, 2019, 10:16:26 PM1/4/19
to tiddl...@googlegroups.com
Mohammad,

On Fri, Jan 4, 2019 at 10:03 PM Mohammad <mohammad...@gmail.com> wrote:
Brian,
Does enlist work with title have space?

Yes. The description at https://tiddlywiki.com/#enlist%20Operator, shows an example of that.

Also, you can paste the code I gave into tiddlywiki.com and see it in action. All the results are tiddlers containing spaces.

Brian

Mohammad

unread,
Jan 4, 2019, 11:56:18 PM1/4/19
to TiddlyWiki
Thanks Brian,
I will back to you after making some experiments with enlist.

Cheers
Mohammad

Mohammad

unread,
Jan 5, 2019, 2:52:21 AM1/5/19
to TiddlyWiki
Hello Brian,
 Have a look at the below code

<$set name="v" value="""a b "this is a test" [[title with space]] """>
<$list filter="[enlist
<v>]" >
<
<currentTiddler>><br>
</$list>
</$set>

If you test this on tiddlywiki.com, it will result in:


a
b
"this
is
test"

title
with space

Which seems to be incorrect!

The correct result is:

a
b
this is test
title
with space

What goes wrong here?

-- Mohammad

Brian Theado

unread,
Jan 5, 2019, 9:21:24 AM1/5/19
to tiddl...@googlegroups.com
Mohammad,

The only punctuation I'm aware of which can enclose spaces in tiddler titles are the open and close double square braces. As you've seen in your experment, quotation marks do not serve that purpose. So my answer of "yes it works with spaces" is more accurate as "yes, as long as the proper punctuation is used"

--
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 post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.

bimlas

unread,
Jan 5, 2019, 12:41:06 PM1/5/19
to TiddlyWiki
Xavier,

Thanks, I didn't know this option.

bimlas

unread,
Jan 5, 2019, 12:45:51 PM1/5/19
to TiddlyWiki
Brian,

I know the use of variables, but it is not a solution for me now. First, I need to iterate through the tiddlers and filter out those that don't fit into the context, after that collect the tags of the remaining tiddlers.

In fact, only collecting the tags is a problem because I need to collect all of them in advance so that there are no mixed tags and tiddlers in the listing.

BTW thanks for your suggestion!

Mark S.

unread,
Jan 5, 2019, 1:37:26 PM1/5/19
to TiddlyWiki
Hi bimlas,

It took me awhile to understand what you wanted. What you want can be achieved with the Wikify widget. This is what I discovered from another thread post by Tony.

So it goes approximately (exact syntax will vary -- untested code -- I'll let you bang your head working out the details ;-) )

\define mytiddlerslist()
<$list filter="[has[myfield]tags[]]"><$view field=title/></$list>
\end
<$wikify name="mytiddlers" text=<<mytiddlerslist>>>
<$list filter="<mytiddlers>"/>
</$wikify>

Note that I didn't have to eliminate duplicate tags -- all TW lists are "compressed" automatically. That's either a feature or a problem, depending on what you want.

HTH
-- Mark

```
In the list of tiddlers
  If tiddler meets a condition
    Add its tags to a list of tags
  end
end

Filter out duplications from the list of tags
Show the list of tags
```

bimlas

unread,
Jan 5, 2019, 4:41:16 PM1/5/19
to TiddlyWiki
Mark,

Thank you very much! I already know how to use wikify, but I did not think I could access the program flow that is common in other programming languages with the help of it! This is a great way to prepare the tiddler list in a separate block.


bimlas

unread,
Jan 5, 2019, 4:44:08 PM1/5/19
to TiddlyWiki
TonyM,

Thanks for the information. I knew I could use lists in the button, but I was trying to get the kind of logic that Mark replied: create a list of tiddlers in a separate block. The answer is wikify, which I know from you, so thank you again! :)

bimlas

unread,
Jan 5, 2019, 4:52:02 PM1/5/19
to TiddlyWiki
Side note:

You have to "encapsulate" the tiddler names, because tiddler titles whose contain space will not listed correctly.

<$list filter="[has[myfield]tags[]]"><$text text="[["/><$view field=title/><$text text="]]"/></$list>

TonyM

unread,
Jan 5, 2019, 5:14:03 PM1/5/19
to TiddlyWiki
Bimlas,

The above example would require text=""" text here """ surely?

Thanks for the feedback

Tony

bimlas

unread,
Jan 6, 2019, 5:16:07 AM1/6/19
to TiddlyWiki
Tony,

Sorry, could you tell me more about what you mean? I don't understand.

TonyM

unread,
Jan 6, 2019, 5:29:29 AM1/6/19
to TiddlyWiki
Bimlas,

The value in your example for text=
Includes quotes " so you have to wrap the whole value in """tripple quotes""" to delimit where the value begins and ends.

Regards
Tony

TonyM

unread,
Jan 6, 2019, 6:03:44 AM1/6/19
to TiddlyWiki
Bimlas,

Why not create a single filter that lists the tags of all tiddlers that meet your required condition?

You could set a variable using the set widget and its filter parameter and every time you use your new variable it will contain what you are asking for and remain upto date. Put it in a global macro if you want it available globaly.

You see, tiddlywiki is made for handling its own content, by trying to picture the process as we would in a proceedural language we make it harder than it need be.

I will post the actual filter if you ask.

Regards
Tony

Mohammad

unread,
Jan 9, 2019, 4:12:57 AM1/9/19
to TiddlyWiki
Thank you for clarification Brian.

--Mohammad

Mohammad

unread,
Jan 9, 2019, 5:27:34 AM1/9/19
to TiddlyWiki
Mark,
 I like your solution as you pass a macro output as a filter to a list widget by using Wikify widget.

No it works great:

\define mytiddlerslist(myfield)
<$list filter="[has[$myfield$]tags[]]"><$view field=title/> </$list>
\end


<div class="dynamic-table">
<$wikify name="mytiddlers" text=<<mytiddlerslist caption>>>
<$list filter=<<mytiddlers>> >
 <span class="ditem">
  <$transclude tiddler="$:/
core/ui/TagTemplate"/>
 </span>
</$list>
</$wikify>
</div>


<style>
.dynamic-table {
  max-width:700px; /* could transclude tiddler width instead */
  -ms-box-orient: vertical;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -moz-flex;
  display: -webkit-flex;
  display: inline-flex;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
  flex-direction: row;
}

.ditem {
  max-width:160px; min-width:160px;
  flex: 0 0 2em; /* -grow, -shrink, -basis */
}
</style>Enter code here...

Create a tiddler in tiddlywiki.com and paste above code inside it.

What I am curious about it is as below
  1. Is this a way to use the value of some variable in different scope or program flow as Bimlas asked in his first post?
  2. Why the code does not work without wikify widget? This is important question: why maco call cannot directly be used?

-- Mohammad

Mark S.

unread,
Jan 9, 2019, 10:17:49 AM1/9/19
to TiddlyWiki


On Wednesday, January 9, 2019 at 2:27:34 AM UTC-8, Mohammad wrote:
Mark,


What I am curious about it is as below
  1. Is this a way to use the value of some variable in different scope or program flow as Bimlas asked in his first post?
  2. Why the code does not work without wikify widget? This is important question: why maco call cannot directly be used?

-- Mohammad



Hi Mohammad,

1. If I understand your question, and Bimlas' question, then the answer is a qualified "yes". Under some circumstances it allows flows that are otherwise impossible.

For instance, if you have a set of tags and want use a count of each one as the input to another macro, perhaps for graphing purposes, you immediately encounter a problem: the count operator generates exactly one output. The only way to get an output like "5 12 16" is take a series of list outputs and combine them via wikify.

2. You can't use the output of a widget as the input to the attribute of another widget. That is, you can't do something like:

<$widget name=<$otherwidget attrib="stuff"/>/>

Widgets are like HTML tags, and you can't pass a HTML tag to the attribute of another HTML tag.

Also, a filter wants a single string with no line breaks: "[tag[stuff]has[field]]" but the list widget outputs everything with line breaks. OK, I "think" it outputs with linebreaks. It's hard to tell because if you let the browser render the output without explicitly putting in <br/> the browser renderer compresses out the line spaces.In any event, if you let Wikify do the rendering, any excess linefeeds will be removed before conversion to a string, just like the browser renderer does.

HTH
-- Mark

Mohammad

unread,
Jan 11, 2019, 1:43:56 AM1/11/19
to TiddlyWiki
Thank Mark!
Thank you for clarification.

--Mohammad

Mohammad

unread,
Jan 11, 2019, 4:00:30 AM1/11/19
to TiddlyWiki
Mark one more question:

\define conc() comment on {{!!title}}

\define create-commentTid()
<$wikify name="ctitle" text=<<conc>> >
<$action-createtiddler 
 $basetitle=<<ctitle>>
 $savetitle="$:/temp/commentName"
 relationship="comment" 
 parent=<<currentTiddler>> 
/> 
<$action-navigate 
 $to= {{$:/temp/commentName}} 
/>
</$wikify>
\end

<$button actions=<<create-commentTid>> >
Click to make a comment 
</$button>


The above code works in Tiddlywiki.com. The idea borrowed from Joe in this post: https://groups.google.com/d/msg/tiddlywiki/BwE0KM_sBJc/AV58mzXnCAAJ

Why this code works while a widget is passed as parameter attributes to another widget?

-- Mohammad

Mark S.

unread,
Jan 11, 2019, 10:01:13 AM1/11/19
to TiddlyWiki
Hi Mohammad,

I don't see anywhere that a widget is passed as a parameter to another widget. I guess you mean:


actions=<<create-commentTid>>


because create-commentTid CONTAINS widgets. But wrapping it in a macro first causes it to be rendered before being passed. I guess I should say that a widget attribute cannot use another widget as input DIRECTLY.

Before we had the Wikify widget, my main trick was to have a series of macros, each of which rendered the output of the prior macro. It made the code very hard to read and was easy to get wrong.

-- Mark

Mohammad

unread,
Jan 11, 2019, 10:36:43 AM1/11/19
to TiddlyWiki
Many Thanks Mark.

I bookmark this.


Cheers
Mohammad

TonyM

unread,
Jan 13, 2019, 12:29:45 AM1/13/19
to TiddlyWiki
Further to my Last Comments

Are these filters not generating what you are asking for?

;Unique Tags on All tiddlers that are "Filter Operators"
<$list filter="[tag[Filter Operators]tags[]sort[]] -[[Filter Operators]]">
   
{{||$:/core/ui/TagTemplate}}
</$list>


;List of All Filter Operators and the tags on each


<$list filter="[tag[Filter Operators]]">
  <$list filter="[all[current]tags[]sort[]]  -[[Filter Operators]]" variable=tag>
       <<currentTiddler>>: <$view tiddler=<<tag>> field=title/
><br>
 
</$list>
</
$list>


Regards
Tony

On Friday, January 4, 2019 at 11:06:49 PM UTC+11, TonyM wrote:
Bimlas,

I will look in more detail later, but remember if you have a macro that generates a list of titles you can use that macro in a widget or other macro to act on the members of that list.

I know its a quick tip only but may get you there.

Tony

TonyM

unread,
Jan 13, 2019, 12:30:52 AM1/13/19
to TiddlyWiki
Duplicate Post in Context

Further to my Last Comments

Are these filters not generating what you are asking for?


;Unique Tags on All tiddlers that are "Filter Operators"
<$list filter="[tag[Filter Operators]tags[]sort[]] -[[Filter Operators]]">
   
{{||$:/core/ui/TagTemplate}}
</$list>


;List of All Filter Operators and the tags on each


<$list filter="[tag[Filter Operators]]">
  <$list filter="[all[current]tags[]sort[]]  -[[Filter Operators]]" variable=tag>
       <<currentTiddler>>: <$view tiddler=<<tag>> field=title/
><br>
 
</$list>
</
$list>


Tony
Reply all
Reply to author
Forward
0 new messages