[tw5] CycleTags button in TW5?

376 views
Skip to first unread message

Måns

unread,
Jul 1, 2014, 2:38:15 AM7/1/14
to tiddl...@googlegroups.com
Hi TwWizards

I wonder if it is possible to create a button which will set and unset tags from a predefined row of tags. I want to be able to cycle through 4 "stages": A, B, C and none of these three tags...

Can I do this already? - or do I need a specialized Widget for it?

Cheers Måns Mårtensson

Stephan Hradek

unread,
Jul 1, 2014, 4:50:46 AM7/1/14
to tiddl...@googlegroups.com
Provided you do not need any other tag:

<$list filter="[is[current]field:tags[]]"><$button set="!!tags" setTo="A">A</$button></$list>

<$list filter="[is[current]field:tags[A]]"><$button set="!!tags" setTo="B">B</$button></$list>

<$list filter="[is[current]field:tags[B]]"><$button set="!!tags" setTo="C">C</$button></$list>

<$list filter="[is[current]field:tags[C]]"><$button set="!!tags" setTo="">clear</$button></$list>



Stephan Hradek

unread,
Jul 1, 2014, 6:10:51 AM7/1/14
to tiddl...@googlegroups.com
A more generic approach. Create a tiddler "cycleTags"

\define btn()
<$button set="$(transcluder)$!!tags" setTo={{!!title}}><$view field="title">clear</$view></$button>
\end
<$set name="transcluder" value={{!!title}}>
<$list filter="[[]] [is[current]list[!!tagcycle]] +[after{!!tags}] [[]] +[limit[1]]"><<btn>></$list>
<$set>

Put this into your tiddler you want to rag:
{{!!title||cycleTags}}

Or this if you want to tag another tiddler from somewhere:
{{My Tiddler to tag||cycleTags}}

Add a field "tagcycle"to the tiddler to tag which contains the tags youwamnt in the sequence you want them ("A B C")

Jeremy Ruston

unread,
Jul 1, 2014, 9:44:53 AM7/1/14
to TiddlyWiki
Hi Stephan

{{!!title||cycleTags}} can be abbreviated to {{||cycleTags}}. See:


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



--
Jeremy Ruston
mailto:jeremy...@gmail.com

Måns

unread,
Jul 1, 2014, 10:41:31 AM7/1/14
to tiddl...@googlegroups.com
Hi Stephan

Very nice solutions - both of them! Thank you very much :-)
They both do what I need now and it doesn't matter that they use all of the tagfield value..
I guess I could change it to work on any other field if I want other tags to the tiddlers..

Of course I'm also wondering if it is possible to create yet another generic tagcycler which will allow other tag values on a tiddler side by side - and not overwrite them... eg. "task" + a cycle of tags like: "urgent" or "[[on hold]]" or "done" etc..

Thanks again - Your help is very much appreciated :-)

Cheers Måns Mårtensson

cmari

unread,
Jul 1, 2014, 11:57:19 AM7/1/14
to tiddl...@googlegroups.com
If you'll please not laugh too loudly, here's what I've been doing with mangletags.  It cycles through a list of tags, leaving other tags in place.  It works pretty well, except I don't know how to go back to the beginning of the list once the end has ben reached.  Any help would be gratefully accepted!

For this example, create a tiddler called Daylist, and give it a list field containing "Mon Tue Wed ..."
In your tiddler where you want to cycle the tags, add the tag Mon, and create a field "current" with the same value as the tag (Mon). 
Then either put the code inside that tiddler or use the {{||cycleTags}} option. 
Code:
\define nexttag(now)
[list[Daylist]after[$(now)$]]
\end

\define swaptag(to, newtag, oldtag)
<$setfield set="$to$!!current" setTo="$newtag$">
<$mangletags find="$(oldtag)$" add="$newtag$" message="tw-set-field">
<$button message="tw-mangle-tags"> cycle </$button><br></$mangletags></$setfield>
\end

\define prepare2()
<$macrocall $name="swaptag" to={{!!title}}  newtag=<<definenexttag>>/>
\end

<$set name="now" value={{!!current}} >
<$set name="oldtag" value=<<now>> >

<$list filter=<<nexttag>> variable="definenexttag" >

<$list filter="[all[current]]">
<$link>{{!!title}}</
$link> <<prepare2>><br>
</$list>

</
$list>

</$set>
</
$set>

cmari

Stephan Hradek

unread,
Jul 1, 2014, 12:35:04 PM7/1/14
to tiddl...@googlegroups.com, jeremy...@gmail.com


Am Dienstag, 1. Juli 2014 15:44:53 UTC+2 schrieb Jeremy Ruston:
Hi Stephan

{{!!title||cycleTags}} can be abbreviated to {{||cycleTags}}. See:


That's great! You see: I still have 5.0.8 experience, where it was required.

Stephan Hradek

unread,
Jul 1, 2014, 12:42:51 PM7/1/14
to tiddl...@googlegroups.com

First I think

[list[Daylist]after[$(now)$]]



should be

[list[Daylist]after[$now$]]



But I might be mistaken.

Then I think this should help you go to the start:

[list[Daylist]after[$now$]] [[list[Daylist]first[]] +[first[]]



At least I hope.

This would add the first element of Daylist after your "next" element.
[[list[Daylist]first[]]



So if you have a "next" element, you will now have 2 elements. If there was no "next" element, you will just have the first of the daylist.

This then will limit the result to the first element
+[first[]]





Måns

unread,
Jul 1, 2014, 5:47:46 PM7/1/14
to tiddl...@googlegroups.com
Hi cmari and Stephan

If I write:

\define nexttag(now)
[list[Daylist]after[$(now)$]][list[Daylist]first[]]+[first[]]
\end

seems to work fine :-)

@cmari - Matabele's widgets: mangletags and setfield are very powerfull indeed - Nice to see how you make them work in this context!! :-)

Cheers Måns mårtensson

cmari

unread,
Jul 1, 2014, 7:50:16 PM7/1/14
to tiddl...@googlegroups.com
Thank you both, Måns and Stephan - that's a great improvement!  I think I've said before that I don't understand why parentheses are needed in situations like [$(now)$], but they are clearly required in this case (omitting them causes the tag to switch to the item "before" rather than "after").
cmari

Stephan Hradek

unread,
Jul 2, 2014, 1:32:39 AM7/2/14
to tiddl...@googlegroups.com

Can you upload your wiki because this absolutely makes no sense.

When I put this into the current tiddlywiki.com wiki:

\define test(now)

|Brackets |$(now)$ |
|None |$now$ |

\end

! with a set
 
<$set name="now" value="I'm from a set">

<<test "I'm a parameter">>

</$set>

! without set

<<test "I'm a parameter">>


I get


Måns

unread,
Jul 2, 2014, 9:24:58 AM7/2/14
to tiddl...@googlegroups.com

Stephan Hradek

unread,
Jul 2, 2014, 9:43:00 AM7/2/14
to tiddl...@googlegroups.com
Am Mittwoch, 2. Juli 2014 15:24:58 UTC+2 schrieb Måns:

That explains it all!

Remove the parameter "now" from the macro definition and it still works. You set a variable "now" where the value of "$(now)$" is taken from. no matter what you pass to the macro.

Matabele

unread,
Jul 3, 2014, 11:00:15 AM7/3/14
to tiddl...@googlegroups.com
Hi cmari

A variable set with the <$set> widget must be called with the syntax $(variable)$.

A variable passed as a parameter to a macrocall must be called with the syntax $parameter$.

In your case you have set the value of the variable 'now' with a <$set> widget:

<$set name="now" value=[[!!current}}>

In the macro, therefore, the correct syntax is $(now)$

In this case, when calling the macro <<nexttag>> -- no parameter is passed with the call, and the (now) parameter of the macro definition is superfluous. The definition should read:

\define nexttag()
...

regards 

Matabele

unread,
Jul 3, 2014, 11:59:43 AM7/3/14
to tiddl...@googlegroups.com
Hi Mans

I tidied the code a little whilst working out how the code works:

\define nexttag()
[list[Daylist]after[$(oldtag)$]][list[Daylist]first[]]+[first[]]
\end

\define swaptag(newtag)
<$setfield set="!!current" setTo="$newtag$">

<$mangletags find="$(oldtag)$" add="$newtag$" message="tw-set-field">
<$button message="tw-mangle-tags">Cycle Tags</$button>
</
$mangletags></$setfield>
\end

<$set name="oldtag" value={{!!current}}>
<$list filter=<<nexttag>> variable="getnexttag" >
<$macrocall $name="swaptag" newtag=<<getnexttag>>/>
</
$list>
</$set>

regards

Matabele

unread,
Jul 3, 2014, 12:51:20 PM7/3/14
to tiddl...@googlegroups.com
Hi

To avoid the necessity for separate tiddlers for each list, lists may be stored as data entries in a data dictionary (here titled 'lists'):

days: Sun Mon Tue Wed Thu Fri Sat
months
: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

-- then:

\define nexttag()
[list[lists##days]after[$(oldtag)$]][list[lists##days]first[]]+[first[]]
\end

regards

On Tuesday, July 1, 2014 8:38:15 AM UTC+2, Måns wrote:

Måns

unread,
Jul 3, 2014, 8:30:12 PM7/3/14
to tiddl...@googlegroups.com
Hi Matabele

 
To avoid the necessity for separate tiddlers for each list, lists may be stored as data entries in a data dictionary (here titled 'lists'):

days: Sun Mon Tue Wed Thu Fri Sat
months
: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec

-- then:

\define nexttag()
[list[lists##days]after[$(oldtag)$]][list[lists##days]first[]]+[first[]]
\end

That's very,very nice :-)

Great to see practical use of a data library/catalog.. - gives food for thought.

I can't help wondering if:

Is it possible to change the "library index" part (lists##days)to a variable eg.: lists##$variable$ and make the "current" part(s) (set="!!current" and <$set name="oldtag" value={{!!current}}>) also into a variable and turn everything into a single cycle tags macro where you specify the tiddler and the list eg.: 

<<cycleTags "TiddlerName" "days">> or <<cycleTags ""(current) "months">> ??

Cheers Måns Mårtensson

Matabele

unread,
Jul 4, 2014, 2:05:14 AM7/4/14
to tiddl...@googlegroups.com
Hi Mans

After further testing, I have found that fields work better than data entries -- especially when switching from one list to another. A single tiddler may still be used for the lists -- the lists being placed in fields rather data entries and called with: 

lists!!days

 -- rather than 

lists##days

It is possible to use a variable -- in general this requires the use of <$set> widgets, as in:

<$set name="list" value="lists!!days">
<$set name="target" value="Title">

-- or even

<$set name="list" value={{!!list}}>
<$set name="target" value={{!!title}}>

These variables can then be used in the macrocalls, for example:

\define nexttag()
[list[$(list)$]after[$(oldtag)$]][list[$(list)$]first[]]+[first[]]
\end

regards

On Friday, July 4, 2014 2:30:12 AM UTC+2, Måns wrote:
Hi Matabele

cmari

unread,
Jul 6, 2014, 10:58:32 AM7/6/14
to tiddl...@googlegroups.com
Hi Matabele,
Thanks so much for both the very clear and succinct summary of correct syntax and the tidied code! 

cmari


--

Matabele

unread,
Jul 7, 2014, 3:18:56 PM7/7/14
to tiddl...@googlegroups.com
Hi

Here's an alternative method using both the <$mangletags> and the <$setfield> widget:

<$list filter="[list[lists!!days]after{!!current}][list[lists!!days]first[]]+[first[]]" variable="getnexttag">
<$setfield set="!!current"  setTo=<
<getnexttag>> >
<$mangletags find={{!!current}} add=<
<getnexttag>> message="tw-set-field">

<$button message="tw-mangle-tags">Cycle Tags</$button>
</$mangletags></$setfield>
</$list>

regards

cmari

unread,
Jul 8, 2014, 11:31:56 AM7/8/14
to tiddl...@googlegroups.com
Stephan, I somhow missed this illustration when you first posted it.  It was really helpful - thanks!  Also, once I saw it, I was reminded of one of your earlier illustrations here:
https://groups.google.com/forum/?hl=en#!topicsearchin/tiddlywiki/myvar/tiddlywiki/4Hlv2Sn5TYc

Working through the specific cycle tags example with the benefit of your general illustrations and Matabele's definitions and code tweaks has been a great way to increase my own understanding of both the SetWidget and the MacroCallWidget.  So thanks again to both of you!
(As a non-expert, I'm never sure whether documentation is "missing" or whether I'm simply not getting the full benefit of existing documentation because I don't understand what I'm seeing). 
cmari




Matabele

unread,
Jul 15, 2014, 2:20:54 AM7/15/14
to tiddl...@googlegroups.com
Hi

I have added some useful illustrations at: http://gwiz.tiddlyspot.com/

Have a look at these demos:
-- Cycle Tags Demo
-- Demo for Richard

regards


On Tuesday, July 1, 2014 8:38:15 AM UTC+2, Måns wrote:

Tobias Beer

unread,
Nov 16, 2014, 5:12:13 PM11/16/14
to tiddl...@googlegroups.com
I think the tags to be cycled should *not* be defined at the tiddler to be tagged but via some transclusion parameter as proposed here:

Best wishes, Tobias.

Tobias Beer

unread,
Nov 16, 2014, 5:19:46 PM11/16/14
to tiddl...@googlegroups.com
Hi Metabele,
 
<$list filter="[list[lists!!days]after{!!current}][list[lists!!days]first[]]+[first[]]" variable="getnexttag">
<$setfield set="!!current"  setTo=<
<getnexttag>> >
<$mangletags find={{!!current}} add=<
<getnexttag>> message="tw-set-field">
<$button message="tw-mangle-tags">Cycle Tags</$button>
</$mangletags></$setfield>
</$list>

Sorry to say, but when I see this syntax I so miss TWc and plain JavaScript.
Not trying to judge anyone or anything... syntactically, this feels horrible and I don't even know where to start looking in the TW5 textbook.

Best wishes, Tobias.

PMario

unread,
Nov 17, 2014, 6:38:30 AM11/17/14
to tiddl...@googlegroups.com
IMO the problem with the syntax is, that nobody uses indentation and we have no proper syntax highlighting in edit mode, for TW syntax yet.


<$list filter="[list[lists!!days]after{!!current}][list[lists!!days]first[]]+[first[]]" variable="getnexttag">
  <$setfield set="!!current"  setTo=<
<getnexttag>> >
    <$mangletags find={{!!current}} add=<
<getnexttag>> message="tw-set-field">
      <$button message="tw-mangle-tags">Cycle Tags</$button>
    </$mangletags>
  </$setfield>
</$list>

With the wikitext parser this may or may not be a syntax problem. ... Most of the time it's not, because whitespace is ignored. The problem is "most of the time :)"  So the user has to know the parser very well.

On the other hand widgets are not supposed to be used by "standard users", because the standard functions should be macros, like <<list-links>>, <<tabs>>, <<toc>>, <<toc-expandable>>, <<toc-selective-expandable>>, <<version>> ...

But at the moment we are in a stage, where we still need to find out, which "core" macros should be there and which parameters they should have. ... Since TW5 is completely different to TWc imo it doesn't make sense to translate TWc macros 1:1. We need to design them from scratch. In the long run, imo this will be an advantage.

In the short run, there's still something missing for new users. IMO your experience and input is highly welcome here :)

have fun!
mario

Jeremy Ruston

unread,
Nov 17, 2014, 6:33:49 PM11/17/14
to TiddlyWiki
Hi Tobias

Sorry to say, but when I see this syntax I so miss TWc and plain JavaScript.

JavaScript hasn't gone away in TW5. The TW5 core doesn't support inline JavaScript within wikitext for security reasons. Bear in mind that when running under Node.js JS code usually has the same security rights that you do. It wouldn't be acceptable for me to be able to import a tiddler that deletes all my files when rendered under the Node.js edition.

JavaScript modules are not particularly complex in TW5 - have a look at the JS macros in the core, for a simple example.
 
Not trying to judge anyone or anything... syntactically, this feels horrible and I don't even know where to start looking in the TW5 textbook.

The docs needs work. More to the point, complex things are complex. The example you quoted to Matabele above is an attempt to build a fairly complex little UI gadget and would be non-trivial in either JS or wikitext.
 

Best wishes, Tobias.

--
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 http://groups.google.com/group/tiddlywiki.
For more options, visit https://groups.google.com/d/optout.

Tobias Beer

unread,
Nov 17, 2014, 7:40:44 PM11/17/14
to tiddl...@googlegroups.com, jeremy...@gmail.com
The docs needs work. More to the point, complex things are complex. The example you quoted to Matabele above is an attempt to build a fairly complex little UI gadget and would be non-trivial in either JS or wikitext.

I very much agree.

My pain point being that understanding and leveraging all this high-level syntax correctly appears to require unveiling a lot more concealed, under-the hood knowledge than a "trivial" js-script used to.

Anyhow, I think I'll finally give it a shot, stop shying from plugin development and start fiddling with the basics to get the gist of it.

In general, I have the impression that plugins...
  • mostly center around new widgets, extending widget functionality
  • perhaps js macros or macros simplifying widget use on top
  • stylesheet shadows to make it look right
  • language shadows for localization (, preferably dictonary tiddlers?)
  • configuration shadows (, also dictionary tiddlers?)
Perhaps missing from the developer docs, what are the standards / recommendations for extending the system-tiddler namespace when it comes to plugin modules / components? Is the recommendation to simply put it all under $:/plugins/githubuser/pluginname/?

Best wishes, Tobias.

Jeremy Ruston

unread,
Nov 18, 2014, 4:18:43 AM11/18/14
to Tobias Beer, TiddlyWiki
Hi Tobias

> My pain point being that understanding and leveraging all this high-level syntax correctly appears to require unveiling a lot more concealed, under-the hood knowledge than a "trivial" js-script used to.

Yes, except that the "concealed, under-the-hood knowledge" is just poor documentation.

Perhaps missing from the developer docs, what are the standards / recommendations for extending the system-tiddler namespace when it comes to plugin modules / components? Is the recommendation to simply put it all under $:/plugins/githubuser/pluginname/?

Yes, that's the best practice. It isn't enforced as a restriction because there are some situations where a plugin needs to define a shadow tiddler outside its namespace. For example, the core plugin defines "GettingStarted", "$:/ControlPanel" etc. as shadow tiddlers. Other plugins may want to provide defaults (eg visibility of toolbar buttons that they include).

Best wishes

Jeremy.
 

Best wishes, Tobias.

William Jackson

unread,
Nov 21, 2014, 8:16:12 AM11/21/14
to tiddl...@googlegroups.com, Tobias Beer
Hi

I believe the widget syntax might be more intuitive using the action widget type syntax -- I haven't yet experimented to see what can be done with the new <$action-setfield> widget.

The filter syntax didn't come from the documentation -- I cribbed it from someone else's example:


filter="[list[lists!!days]after{!!current}][list[lists!!days]first[]]+[first[]]"

-- I agree; would be nice if this was easier to understand! I suppose a widget that cycles through a space separated list might do the trick.

regards



--
You received this message because you are subscribed to a topic in the Google Groups "TiddlyWiki" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywiki/P3cw2gILiFU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywiki+...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages