[How to] [TW5] Multiple tag fields

1,001 views
Skip to first unread message

Duarte Farrajota Ramos

unread,
Sep 13, 2015, 6:46:35 PM9/13/15
to TiddlyWiki
Hello, everyone
I've been using TiddlyWiki 5 happily for a few months now, for all my personal note taking and offline local knowledgebase, but one thing was keeping me from doing a full transition of all my data, and that was being able to have multiple tag fields per tiddler.
I figured out a relatively easy way to have multiple tag fields in a tiddler (sort of) and decided to share it here as reference since I've seen the same question popup a few times before, and maybe it is useful to someone else.


Disclamer

This isn't a true multiple tag field per tiddler, tags are all still store in the default built in tags field, me and my (very) limited coding skills haven't figured out entirely how to do that just yet.
This is just a hack to work around the missing desirable functionality, and simulate that feature, it is however, from a user point of view, both for viewing and editing purposes virtually the same as having as many tag fields as you like.

A little background

I'll use as an example the one piece of data I had yet to convert to a TiddliWiki format: my Software Database. I like trying out new software and always looking for better alternatives for what I currently use, and in the process I like to keep a record of what I find, where to get it from and it's strengths and weaknesses and features.I also like keeping some useful more technical info about them, like for example input and output file formats and protocols for each application.
This is where multiple tag fields come in handy, I'd like to have a field for input where I could specify that said program can read formats like say PSD, SVG, PDF and output or save to formats like Jpeg, Tiff or PNG. This could easily be done in the tag field, but I would like to keep that reserved for actual "categories" of software (like Image editors, or Text Editors, File Browsers etc.) and having file format tags there would quickly encumber it with a huge amount of tags, while still being hard to distinguish between input and output for each application without having to duplicate the set of tags.

Principle

So the trick here is filtering tags, if you do this to your tiddlywiki you'll basically end up with a different set of tags for each "custom field" that you would add, distinguished by a certain feature, either by name, by a certain tag, presence of a field, or any other filterable option.
After that all you have to do is filter out each set of undesirable set tags for each context.

How to

So following the above example of the software database lets image you want to have an Input field and an Output field for each tiddler tagged with Software and for each of these there will be a set of file format and protocol tags that can be assigned independently to each field. Instead of creating theses fields what we will do is create a different set of tags with a specific naming convention that will only e shown in the correct context.
For my use case I chose to distinguish these tags by name (could be with a tag or field or any other difference that can be filtered or with wiki text filters) , so all input tags would be named according to this scheme "Format/Input/File Type Name" and all output tags would be named "Format/Output/File Type"
Now first step would be to make sure these tags stay out of your way in the "regular" tag field; to do so you have to search for your tag editor system tiddler $:/core/ui/EditTemplate/tags

  1. Search for $:/core/ui/EditTemplate/tags with the Advanced Search/System dialog.
  2. Overwrite the system tiddler by making a copy with the exact same name (erase the number at the end)
  3. Now you need to override the tags that are shown both in the dropdown search popup and the already applied tags by editing by editing the filters
    1. Edit the field mangler line <$list filter="[all[current]tags[]sort[title]]" storyview="pop"> to never display tiddlers that start with "Format/" in their name by replacing it with the prefix operator
      <$list filter="[all[current]tags[]!prefix[Format/]sort[title]]" storyview="pop">
    2. Edit the linkcatcher line <$list filter="[tags[]!is[system]search:title{$:/temp/NewTagName}sort[]]"> to never display tiddlers that start with "Format/" in their name by replacing it with the prefix operator
      <$list filter="[tags[]!prefix[Format/]!is[system]search:title{$:/temp/NewTagName}sort[]]">

  4. To be able to display the tags correctly you need to do the same in the view template $:/core/ui/ViewTemplate/tags to exclude undesirable tags
    1. Search for $:/core/ui/ViewTemplate/tags with the Advanced Search/System dialog.
    2. Overwrite the system tiddler by making a copy with the exact same name
    3. Replace the filter <$list filter="[all[current]tags[]sort[title]]" template="$:/core/ui/TagTemplate" storyview="pop"/> with
      <$list filter="[all[current]tags[]!prefix[Format/]sort[title]]" template="$:/core/ui/TagTemplate" storyview="pop"/>

  5. Now you need a way to edit these tags as if they belonged to a different field, for that you need to create an additional tag editor field, in the edit template that similarly filters out undesirable tags, or in this case only includes the tags starting with the prefix "Format/Input/", for that
    1. Search for $:/core/ui/EditTemplate/tags with the Advanced Search/System dialog.
    2. Make a copy of this tiddler with whatever name you want
    3. Edit the field mangler line <$list filter="[all[current]tags[]sort[title]]" storyview="pop">
      to only display tiddlers that start with "Format/Input/", in their name by replacing it with the prefix operator
      <$list filter="[all[current]tags[]prefix[Format/Input/]sort[title]]" storyview="pop">
    4. (For the hypothetical output field one would similarly have to do this with <$list filter="[all[current]tags[]prefix[Format/Output/]sort[title]]" storyview="pop">)

  6. To make this "virtual field" editor completely independent from the regular tag editor we must now change all the state and temp tiddlers that make it work. This is easier to do in an external text editor
    1. Use it's search and replace function to substitute all occurrences of {{$:/temp/NewTagName}}
      with {{$:/temp/NewInputName}} or whichever name you desire
    2. and $:/state/popup/tags-auto-complete with
      $:/state/popup/input-auto-complete

And you should be all set, now you may want to do some filtering so that your additional tag viewers and tag editors only show up in the correct tiddlers (only the ones tagged with Software in this case) by adjusting your view and edit templates with additional filters.

Problems and weaknesses of this method

There are a few caveats to this method, namely you can't really share the exact same tags between different "virtual fields", since you would then have no way to know to which field they are applied to, also there's an additional considerable maintenance overhead, since you'll have to manually distinguish all tags belonging to a certain field, either by assigning a different name system (with a prefix or a suffix) or assigning a certain tag, or adding specific field, so they can be filtered in/out according to context. If you really need this sort of categorization however it may well be worth the extra trouble of maintaining it.

Sorry for the wall of text, I hope this is helpful to other people, also if I'd like to hear your opinion about it or if you have a better method please do share! :)
























PMario

unread,
Sep 14, 2015, 7:16:29 AM9/14/15
to TiddlyWiki
Thanks for sharing!
-m

Tobias Beer

unread,
Sep 15, 2015, 5:41:02 AM9/15/15
to tiddl...@googlegroups.com
Thanks for the instructions,

While a bit blown out of proportion, discussion-wise, here's a related issue about wanting more "tag-fields" and perhaps a desire to leverage the same core tag-components to establish custom tag-collections or tag-sets or whatever you call it, yours having a prefix and being actual tags:


Best wishes, Tobias.

Duarte Farrajota Ramos

unread,
Sep 15, 2015, 7:00:50 AM9/15/15
to tiddl...@googlegroups.com
@Tobias Beer & @PMario Thanks for the comments guys, you're welcome. :)

@Tobias Beer what you describe in that link is a very well worded description of the limitations I found with the current set of tools, and exactly what I envision would be a perfect solution. I sure as hell would love to see it as a plugin, very interesting discussion.
I made a few (very) crude attempts at implementing that myself, by editing the current tag editor tiddler $:/core/ui/EditTemplate/tags, to read from a custom field and list entries from different tiddlers.
I copied code from the current documentation and from a few tips and research I did around the forum, but eventually came to a halt because I couldn't get it to list tags individually, they were grouped together as if the whole content of each tiddler's custom field was a single tag.
I later came up with the solution above which kind of works acceptably for my use case; so I'll leave the code here for anyone smarter than me who cares to look at it. It's probably the wrong way to go about doing it, but maybe it'll inspire someone who actually knows what he's doing to complete it or implement it correctly as a plugin.

This would go as a tiddler tagged with $:/tags/EditTemplate for a custom field named "custom_field_name"

\define lingo-base() $:/language/EditTemplate/
\define tag-styles()
background
-color:$(backgroundColor)$;
\end


<$list filter="[all[current]has[custom_field_name]]" storyview="pop">``
<div class="tc-edit-tags">``
<$fieldmangler>
<$list filter="[each[custom_field_name]get[custom_field_name]]" storyview="pop">``<$set name="backgroundColor" value={{!!color}}><span style=<<tag-styles>> class="tc-tag-label">``
<$view field="title" format="text" />
<$button message="tm-remove-tag" param={{!!title}} class="tc-btn-invisible tc-remove-tag-button">``&times;</$button></span>
</$set>
</
$list>

<div class="tc-edit-add-tag">``
<span class="tc-add-tag-name">``
<$edit-text tiddler="$:/temp/NewCustomEntryName" tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/popup/custom-field-auto-complete">``> class="tc-edit-texteditor tc-popup-handle"/>
</span> <$button popup=<<qualify "$:/state/popup/custom-field-auto-complete">``> class="tc-btn-invisible tc-btn-dropdown" tooltip={{$:/language/EditTemplate/Tags/Dropdown/Hint}} aria-label={{$:/language/EditTemplate/Tags/Dropdown/Caption}}>{{$:/core/images/down-arrow}}</$button> <span class="tc-add-tag-button">``
<$button param={{$:/temp/NewCustomEntryName}} set="
$:/temp/NewCustomEntryName" setTo="" class="">``
<$action-setfield custom_field_name={{$:/temp/NewCustomEntryName}}/>
<<lingo Tags/Add/Button>>
</$button>
</span>
</div>

<div class="
tc-block-dropdown-wrapper">``
<$reveal state=<<qualify "
$:/state/popup/custom-field-auto-complete">``> type="nomatch" text="" default="">``
<div class="
tc-block-dropdown">``
<$linkcatcher set="
$:/temp/NewCustomEntryName" setTo="" message="tm-add-tag">``
``<$list filter="
[search:custom_field_name{$:/temp/NewCustomEntryName} search:title{$:/temp/NewCustomEntryName}sort[]]">``
{{||$:/core/ui/Components/tag-link}}
</$list>
<hr>
<$list filter="
[each[custom_field_name]get[custom_field_name]search:title{$:/temp/NewCustomEntryName}sort[]]">``
{{||$:/core/ui/Components/tag-link}}
</$list>
</$linkcatcher>
</div>
</$reveal>
</div>
</$fieldmangler>
</div>
</$list>

Tobias Beer

unread,
Sep 15, 2015, 8:58:11 AM9/15/15
to TiddlyWiki
Here's how I would envision some "multiple-tag-fields" components to work off the top off my head...

1) the user defines fields that function as tagsets, like all fields in lowercase, which when used are entered and interpreted as if standard tags, but not returned by standard tag filters, e.g.
  • author
  • category
2) for each tagset there's a config tiddler under a dedicated system namespace, e.g.
  • $:/config/tagfieds/author
  • $:/config/tagfieds/category
3) these config tiddlers hold all config parameters leveraged with 4) and 5) for each tagset, e.g.
  • filter
    • specifies for which tiddlers the editor / viewer is displayed at all, default: none (thus all tiddlers)
  • title
    • the name of a corresponding tiddler, so instead of "author" one could reference a tiddler "Authors" or, french, Auteurs
    • a link to that tiddler will be shown in the view-mode component as a kind of section heading
  • list-before / list-after
    • determine how different tag-fields are listed as edit- or view-mode-sections
    • the tag $:/tags/FieldTags can be used to further specify sorting
  • color
    • a color for the tagset
4) edit-mode
  • a component that implements the default edit-tags template, one for each tagset, esp. the popup-adder
  • preferably, the standard component can be reused in a parameterized manner
5) view-mode
  • a component that allows to list all items in a tagset, linking to a tagset-tiddler
  • could be used to create a "new here" item, thus a new tiddler with a field corresponding to the tagset, still emtpy
So, essentially, this would be what you did only just not using actual tags with prefixes, but rather individual fields for each tagset. All tiddlers that are in a tagset are determined using adequate list filters, including some that have been in the pipe for a bit.

— tb

Duarte Farrajota Ramos

unread,
Sep 15, 2015, 11:24:13 AM9/15/15
to TiddlyWiki
Hey I just figured out this can effectively used to have a separate hierarchy of "Categories" and "Tags", where categories can be used for the table of contents sidebar macro, and the tags can be used as regular tags without disrupting the tree view. One can use a prefix like "Toc/###" or "Category/###" for the toc entries.

Spangenhelm

unread,
Sep 17, 2015, 4:13:50 AM9/17/15
to TiddlyWiki
Hi, i'm trying to understand the purpose of this but my mind refuse lol: is there a place where we can see this in action or could you provide a screenshot please ?
I have tried to copy what you have published above but without success..

Thank you

Ps: congratulations too for the poster, looks nice and clean !

Duarte Farrajota Ramos

unread,
Sep 17, 2015, 7:42:37 AM9/17/15
to TiddlyWiki
Hello Spangenhelm, the method explained here is a way to virtually have multiple tag fields on the same tiddler.
It simulates the option of having two or more distinct fields in the same tiddler that behave in the same way that the default tag editor does, with the benefits it brings, like the auto complete, the list of available tags, the tag-pill display etc.
It also creates a separation between a few "set of tags" with different purposes, for example in my software database I find it desirable to tag my software with stuff like "image Editor" "3D Modeling" or "Note Taking", I also like to tag it by platform "Windows" "Mac" Linux" etc.
These tags could all live in the same field, or I could optionally separate them as if they are completely independent sets of tags each with its own field both while reading or editing the tiddler. Same goes for file formats, instead of having dozens of file formats "polluting" my regular tag field I can have them neatly separated into it's own field.

Check a screenshot f the example below:

In edit mode:



And in view mode



Hope this makes it clearer




BTW, glad you like the poster thanks! :)

Tobias Beer

unread,
Sep 17, 2015, 7:51:43 AM9/17/15
to tiddl...@googlegroups.com
Hi Duarte,

Using prefixes looks a bit redundant.

I would rather give every platform-type a tag platform and then construct the filter based off of that, e.g....

[tag[platform]tagging[]]

[tag[output-format]tagging[]]

...and then only use mac, linux windows ...or the corresponding mime types as titles.

Best wishes,

— tb

Duarte Farrajota Ramos

unread,
Sep 17, 2015, 7:57:34 AM9/17/15
to TiddlyWiki
You are right Tobias, nice one! That would indeed be easier in this case.
I guess I just did it blindly for consistency/continuity, since the formats used the prefix method because of the distinction between Input and Output

I'll probably rework those since it's still WIP, there is still no separate editing for platforms yet.

Tobias Beer

unread,
Sep 17, 2015, 8:01:14 AM9/17/15
to TiddlyWiki
I guess I just did it blindly for consistency/continuity, since the formats used the prefix method because of the distinction between Input and Output

...which really begs for using dedicated fields, though, imho. 

Best wishes,

— tb

Duarte Farrajota Ramos

unread,
Sep 17, 2015, 8:29:37 AM9/17/15
to TiddlyWiki
For the formats input and output tags it won't work, because for example a tiddler named JPEG could belong to input or output or both on the same tiddler.

On second though using tags for platforms has undesirable effects, like adding a new platform will not show immediately, since you have to manually create the tiddler and tag it with "Platform"

Separate fields would definitely be the way to go, but it is beyond my skill level

Danielo Rodríguez

unread,
Oct 2, 2015, 4:52:54 PM10/2/15
to TiddlyWiki
I have created a widget called field-mangler-ext that allows you to select to which field add the tags.
It is not perfect, but it works. It's part of a plugin I am working at.

Duarte Farrajota Ramos

unread,
Oct 2, 2015, 7:01:09 PM10/2/15
to TiddlyWiki
Hey Danielo that sounds very interesting, looking forward to that plugin

Jed Carty

unread,
Oct 3, 2015, 6:40:50 PM10/3/15
to TiddlyWiki
This is one of the things I have been poking a bit recently. I have an early version of some modifications that allow multiple tag fields. There are formatting problems but most of the basic parts work.

Currently these work:
tm-add-tag
tm-remove-tag
tag filter operator
tags filter operator

I changed the fieldmangler widget so it takes an optional field parameter to set the field used for the messages, the filter operators use tag:fieldname the same way as the field operator to specify which field is used.

The tagging operator doesn't work yet and is[tag] doesn't work with the alternate fields.

The current demo is here:

http://ooktech.com/jed/ExampleWikis/MultipleTagFields/

Danielo Rodríguez

unread,
Oct 4, 2015, 10:26:31 AM10/4/15
to TiddlyWiki
Hey Jed,

Seems like we have been working on the same stuff. 
Here is my code, let me know if yours is different:


Tobias Beer

unread,
Oct 4, 2015, 11:56:44 AM10/4/15
to TiddlyWiki
Hi Danielo and Jed,

I'm wondering why you two chose to touch the fieldmangler for that.

Best wishes,

— tb 

Jed Carty

unread,
Oct 4, 2015, 3:32:24 PM10/4/15
to TiddlyWiki
Tobias,
Because it was the most straight forward way to extend the tags directly. It turns out that it isn't as efficient, but it has the most you can reuse.

Danielo,

I changed to using action widgets. It turns out it is a much easier way to go and should be better for future updates.
The discussion about it on github is here: https://github.com/Jermolene/TiddlyWiki5/issues/1993#issuecomment-145359568
Here is my new thing: http://ooktech.com/jed/ExampleWikis/ListManipulation/#Demo%20Stuff

RickL

unread,
Oct 5, 2015, 6:46:25 PM10/5/15
to TiddlyWiki
This is a great tool Jed!   It will work great for my project management TW.

Danielo Rodríguez

unread,
Oct 6, 2015, 3:11:22 AM10/6/15
to TiddlyWiki
I have not touched the fieldmangler in any way. Field mangler widget remains untouched, I just extended it and I have created a new widget called fieldmangler-ext 

I changed to using action widgets. It turns out it is a much easier way to go and should be better for future updates.

My field mangler extended relies on action widgets sending the appropriate parameters. Do you mean something different ? 

Jed Carty

unread,
Oct 6, 2015, 5:46:15 AM10/6/15
to TiddlyWiki
I just made a new action widget. It will probably be put into the action-setfield widget if it does make it to the core but this allows things to be much more modular since this is a single file that adds a single widget.

What I have is here http://ooktech.com/jed/ExampleWikis/ListManipulation/#Demo%20Stuff:[[Demo%20Stuff]]%20%24%3A%2Fplugins%2Finmysocks%2FListManipulation%2Faction-editlist.js

It is currently full of bugs when it comes to generic list operations, but it should work when you want it to be like the tag field. The biggest problem with this compared to the other one is that there isn't yet an equivalent to the tag[foo] filter operator for other fields. That is easy enough to add but it may be a few days before I get time to do it.

Reply all
Reply to author
Forward
0 new messages