Hierarchic tag search?

466 views
Skip to first unread message

bimlas

unread,
Oct 16, 2018, 1:49:57 AM10/16/18
to tiddl...@googlegroups.com
Hi!

I'm using tags heavily, for example if I had to write a tiddler about TiddlyWiki, I would apply "Software", "NoteTaking", "Windows", "Linux" so anything that is related to Tiddly.

The tags are sorted in hierarchical way:

Software
  Linux
  TiddlyWiki
  Windows
Attribute
  NoteTaking

I wrote FilteredTags plugin to easily navigate in tags, it lists only those tiddlers that are assigned to each of the selected tags: https://bimlas.gitlab.io/#Filter%20by%20multiple%20tags%20easily%3A%20FilteredTag%20example

If I would have to write a tiddler about a TiddlyWiki plugin, I would apply "TiddlyWiki" and "Plugin" tags. In this case this plugin is not associated to "NoteTaking" tag, thus it will not list if I filter to "NoteTaking" and "Plugin" tags; I would have to add the same tags to the plugin as I did for TiddlyWiki, so the plugin would be associated to "Software", "NoteTaking", "Windows", "Linux" and "Plugin".

Is there a way to see if a tiddler or its parents are associated to given tags (so in the example I would like to know if the plugin or its parents are associated to "NoteTaking" and "Plugin")? I would like to handle tags as (mathematical) sets (https://en.wikipedia.org/wiki/Set_(mathematics)) instead of "labels".

bimlas

unread,
Oct 16, 2018, 2:24:54 AM10/16/18
to TiddlyWiki
Sorry, the formatting was broken, I just fixed it.

TonyM

unread,
Oct 16, 2018, 3:05:26 AM10/16/18
to TiddlyWiki
First,

I am sure the answer is yes to handling tags as mathematical sets. But I am still not clear on your Question, in part because I believe there is basic functionality allowing this, and yet you have already created a plugin.

What do you mean associated? Do you simple mean tagged.

If you have any list generated by a filter you can use this list of tiddlers that result to act as the input to another process. 

When it comes to identifying a single parent on a tiddler you could have a problem if it has multiple tags, one solution is to store the parent in a custom field such as Marios https://wikilabs.github.io/editions/tocP/ ToCP offers.

I can help more but only when I understand your needs better.

Tony

bimlas

unread,
Oct 16, 2018, 4:24:23 AM10/16/18
to TiddlyWiki
Here's a concrete example:

On the Tiddly website int the ToC there's an entry: Features -> Drag and Drop -> DragAndDropMechanism. If I looking for Features, DragAndDropMechanism is not listed, because it's not the direct child of it. 


I would like to find a way that shows me everything which is associated with Features (everything under this tag in the ToC), than I could apply another tag filter on this list (by my plugin).

For example if I looking for "Features" and "Another tag", it would look like this as mathematical sets:

Mark S.

unread,
Oct 16, 2018, 1:33:07 PM10/16/18
to TiddlyWiki
I think the approach would be to make a recursive macro, similar to the TOC macros, that just returns a list of tags including descendant tags. Then wrap that macro call in a wikify widget in order to turn it into an actual list of tags (Wikifying macros is a trick I learned from Tony, BTW).

Of course, if it was something that got a lot of use, then a javascript filter (e.g. "grandtags") might be more versatile.

-- Mark

TonyM

unread,
Oct 16, 2018, 6:43:38 PM10/16/18
to TiddlyWiki
Bimlas,

Thanks that is very nicely presented. I understand now. Recent discussion about TOC's and applying a filter may not exactly solve this.

Effectively you want to define the first set as the members found in a TOC or recursive function then find the members in that set that have "Another Tag"?

This maps closely to work I have being doing lately. Rather that make specific solutions can we generalise it more. In this case we could have our own TOC macro that runs down the hierarchy but only displays items also tagged "Another Tag".

Instead lets find the best way to generate a list of tiddlers from a TOC process that can be used in set filtering.

I will contribute more today.

Tony

TonyM

unread,
Oct 16, 2018, 7:39:16 PM10/16/18
to TiddlyWiki
Bimlas,

Here is a pair of macros that uses recursion to "iterate" the toc hierarchy, but only display the items that also meet the filter provided.

\define each-level(filter)
<$list filter="$filter$" variable=nul>
[[$(currentTiddler)$]]<br>
</$list>
<$list filter="[is[current]tagging[]]">
        <<each-level $filter$>>
</
$list>
\end
\define list-toc(tiddlername filter)
<$tiddler tiddler="$tiddlername$">
   
<$list filter="[is[current]tagging[]]">
       
<<each-level $filter$>>
   
</$list>
</
$tiddler>
\end


<<list-toc TableOfContents "[is[current]!tag[test]]">>
Note the use of !tag[test] you would use tag[Another Tag]]

The next thing to do is to find easy to understand methods of taking the filtered results, a list one 0 or more tiddlers and using them in other ways.



Regards
Tony

TonyM

unread,
Oct 16, 2018, 8:12:29 PM10/16/18
to TiddlyWiki
Also Here is a Parent field based TOC list, but the filter is not implemented.


\define each-child(filter)
[[$(currentTiddler)$]]<br>
<$list filter="[parent[$(currentTiddler)$]]">
       
<<each-child $filter$>>
</$list>
\end
\define list-tocP(tiddlername)
<$tiddler tiddler="$tiddlername$">
   [[$tiddlername$]]<br>
   <$list filter="[parent[$tiddlername$]]">
       <<each-child>>
   </
$list>
</$tiddler>
\end

<<list-tocP "New Home">>

Regards
Tony

bimlas

unread,
Oct 17, 2018, 1:57:50 AM10/17/18
to TiddlyWiki
Whoaaa...! o_O Big respect, it works nicely! ^-^ Just tried out on https://tiddlywiki.com/ with

<<list-toc Features "[is[current]tag[Mechanisms]]">>

I tried to apply more tag filters without success (to show tiddlers related to "Features", "Mechanism", "Drag and Drop"), but I think it would need a different method, because different levels may associated to different tags, but it should filter those which are related to ALL of the given tags.

One more question: I'm sure that I misunderstood something, but why is this listing everything related to "Features"? For example it shows "Using SVG" too, but it's tagged by "Features" only.

<<list-toc Features "[is[current]tag[Drag and Drop]]">>

Anyway: a big thanks for sharing your knowledge with us!

TonyM

unread,
Oct 17, 2018, 7:36:30 AM10/17/18
to TiddlyWiki
Bimlas,

Sorry, I made an assumption I should not have.

The filter can be extended for your use case, you just need to learn the extra steps.

On tiddlywiki.com it says how a filter can be a list of tiddlers "tiddlera [[tiddler b]] tiddler3" but each of these can be a things like [tag[tagname]. And you can exclude items at the end with -[[tiddlername]] or use +[tag[tagname]] and more

When I am on my desktop tomorrow I can generate one for your use case

Tony

bimlas

unread,
Oct 17, 2018, 8:35:22 AM10/17/18
to TiddlyWiki
I just played with your code. As I see, the core of getting everything associated to a given tag would be this:

\define each-level()
 
[[$(currentTiddler)$]]<br>

 
<$list filter="[is[current]tagging[]]">
   
<<each-level>>

 
</$list>
\end
\define list-toc(tiddlername)

  <$tiddler tiddler="$tiddlername$">
    <$list filter="[is[current]tagging[]]">
      <<each-level>>
    </$list>
 
</$tiddler>
\end

<<list-toc Filters>>

It's listing everything which is under "Features" in ToC (regardless of level). If I could get the common elements of <<list-toc Filters>>, <<list-toc Mechanisms>> and any additional lists, then it would be exactly what I like to achieve.

I have to play more, but a big thanks for the code! It helped me a lot.

TonyM

unread,
Oct 17, 2018, 7:42:49 PM10/17/18
to TiddlyWiki
Bimlas,

Remember the solution we have here creates a list of everything in the hierarchy generated from the root tiddler, in this case Features, the filter we provide simply determines what in this hierarchy is displayed.  So in your examples below it is always about the tiddlers found in the tree starting with Features.

The macros I gave you did not account for spaces in the tags, I have added quotes around "$filter$" where ever it occurs.

\define each-level(filter)
<$list filter="$filter$" variable=nul>
[[$(currentTiddler)$]] "$filter$"<br>

</$list>
<$list filter="[is[current]tagging[]]">
        <<each-level "$filter$">>
</
$list>
\end
\define list-toc(tiddlername filter)
<$tiddler tiddler="$tiddlername$">
   
<$list filter="[is[current]tagging[]]">
       
<<each-level "$filter$">>
   
</$list>
</
$tiddler>
\end


With this now working for tags with spaces, The simplest way to extend the filter for your other tags is as follows, not how for each case we must specify [all[current]] (Apparently this is more efficient than [is[current]] which would do the same thing.

<<list-toc Features "[all[current]tag[Drag and Drop]] [all[current]tag[Mechanisms]] [all[current]tag[Features]]">>

Do remember however this only show items in the Features Toc that also have the filtered tags, the following code lists all items with one or more of the tree tags;

<$list filter="[[all[current]tag[Drag and Drop]] [all[current]tag[Mechanisms]] [all[current]tag[Features]]">

</$list>
The result is similar to the featured toc because of the data on Tidlywiki.com

Also; To assist with diagnosing the list I replaced 
[[$(currentTiddler)$]]<br>
With
[[$(currentTiddler)$]] : {{!!tags}}<br>
To show the tags on each tiddler in the Features tree that are displayed


Finally, providing the filter [is[current]] or [all[current]] will display everything in the tree without and additional "filtering"

<<list-toc TableOfContents "[all[current]]">>

Regards
Tony

bimlas

unread,
Oct 18, 2018, 5:11:52 AM10/18/18
to TiddlyWiki
Thanks for your effort!

I just made a filter operator (as TonyM suggested) to gather "family" of a tiddler, the "field of connection" can be set (defaults to "tags"):

[kindred:<direction>[<field>]]


The "base tiddler" is excluded from the list.

For example if I want to show tiddlers where "Drag and Drop" belongs to, I can use

[[Drag and Drop]kindred:up[]]

  • Features 
  • TableOfContents 
  • $:/tags/SideBar
Filter tiddlers belongs to "Drag and Drop" 

[[Drag and Drop]kindred:down[]]
  • DragAndDropMechanism
To get the whole "family":

[[Drag and Drop]kindred[]]
  • Features Features 
  • TableOfContents 
  • $:/tags/SideBar 
  • DragAndDropMechanism
It works on any field, for example "parent" (as PMario's ToCP works) or "list":

[[TableOfContents]kindred[list]]

  • HelloThere 
  • A Gentle Guide to TiddlyWiki 
  • Discover TiddlyWiki
  • ...
  • Encryption
  • Customise TiddlyWiki
  • Initial customisation
  • ...
Your solution works with "OR" condition (if I'm right), but I want to use "AND" when filtering to multiple tags. This operator should work in this way, but I don't know what's the problem: it's showing only the results of the second expression:

[[Filters]kindred[]] +[[Learning]kindred[]]

I tried out with filtering tags, in that case it works as expected: it's showing only https://tiddlywiki.com/#Introduction%20to%20filter%20notation

[tag[Filters]] +[tag[Learning]]

PS.: I'm not strong in English, so please advise another name if it's odd: I looked for a word that describing the parents and the childs at once.

bimlas

unread,
Oct 18, 2018, 5:18:07 AM10/18/18
to TiddlyWiki
Forgot to mention how can you try it out:

TonyM

unread,
Oct 18, 2018, 7:20:35 AM10/18/18
to TiddlyWiki
Bimlas,

That look realy cool, I wish I could write filter operators.

You do some advanced stuff in this community.

I will try it out in time. Im travling interstate for a few days. It sounds like a great tool for heirachies and geneological trees.

I think you may know this but just in case and for other readers,

In the filter examples I gave the OR was given by a list of tag filters surrounded with [ ] and seperated by spaces, the AND opperation is when you dont have spaces between them resulting in less brackets.

[is[current]tag[tag1]tag[tag2]!tag[tag3]]

Noting of course in this I am saying

The current tiddler has the tag tag1 And the tag2 And not the tag3

REGARDS
Tony

bimlas

unread,
Oct 18, 2018, 7:44:49 AM10/18/18
to TiddlyWiki
Just created an example wiki (actually with TW5.com/prerelease). I just realized that you could try it out by drag-n-dropping to another wiki (stable version, not the prerelease) and restart it, but it not works: it's saying "tiddler.getFieldList is not a function" - I have to do some compatibility check.

You do some advanced stuff in this community.

Thank you very much! :) Necessity is the mother of invention - my memory is pure, thus I looked for a good way to store any kind of information on my computer, this is how I found and fall in to love with TiddlyWiki. It has some incompletion, thus I trying to shape it to fill the holes to shape to my needings.
TiddlyWiki-kindred-filter-operator-example.html

bimlas

unread,
Oct 18, 2018, 8:14:24 AM10/18/18
to TiddlyWiki
Done with the compatibility check: "getFieldList" is present only in prerelease, thus this filter operartor works only on that. :(

Behaviour in a nutshell: if the connection check is based on "list" field for example, then the "list" has to be parsed first to make an array from it - by default it's just a string, thus I cannot check that "second" is in "first second third". This functionality is present only in prerelease (converting field to array). 

I could modify the operator to check that field text equals exactly to a tiddler name, but in this case it would not find "Features" in the "list" field of "TableOfContents" -> it would be ineffecient.

What's the "release cycle" of Tiddly? The prerelease when will be released? A week/month/year?

bimlas

unread,
Oct 19, 2018, 9:29:13 AM10/19/18
to TiddlyWiki
I just finished most of the work - the plugin (mostly) works but only on prerelease.

I had to change the syntax, because I misunderstood the "+[...]" filter expression: I thought that I need to collect tiddlers (initialize a list) and return with them to let the `+[...]` filter expression collect the elements common with the previous expression, but instead of this I have to filter the input tiddlers by checking that it's a member of the family or not.

The new syntax is:

[kindred:<field>[<tiddler_from_family>]]
[kindredup:<field>[<tiddler_from_family>]]
[kindreddown:<field>[<tiddler_from_family>]]

Because of this filter behaviour, the "base tiddler" (passed as operand) has to be included in to the output list (I excluded it earlier).

TiddlyWiki-kindred-filter-operator-example.html

bimlas

unread,
Oct 26, 2018, 9:34:36 AM10/26/18
to TiddlyWiki
If anybody interested in it: I just announced a newer version at https://groups.google.com/d/msg/tiddlywiki/YZlPGP0qX1o/IZczi-L8CAAJ
Reply all
Reply to author
Forward
0 new messages