Using the tags field to denote different kinds of relationships / hierarchies within the same wiki

My main tiddlywiki project at the moment is maintaining a reference wiki for the fictional world I run a tabletop roleplaying game in. This is a complex project with involves modelling lots of different relationships between different types of entity that exist within the world (e.g. locations, characters, objects, etc.), and I’ve run into some problems trying to use the tags field and toc macros for different purposes within this single project. For example:

  • Sometimes I want to be able to use the core macros to just see a tag tree of one specific type of entity, e.g. a toc macro that shows me all of the different locations in the world and their sub-locations
  • However, sometimes I want to be able to use those same macros to show a tree that contains multiple different types of entity, e.g. all of the sub-locations within a certain location, and also all of the characters and/or items that are currently within those locations

This is a simple case, but there are more complex ones involving modelling different kinds of relationships, so I’ve tried to create a solution that can be used in the general case.


What I’ve done is used a combination of two custom fields, and a few of the new custom functions:

  • The field parent-tag denotes which entry in a tiddler’s tags field represents its direct parent within the central hierarchical structure of the wiki
  • The field is-root-tag denotes (via “yes” or “no”) whether or not tiddler’s beneath this tiddler in the hierarchy should look to this tiddler as their “root” ancestor, for template information etc.

I then define the following global functions

\function get.root.tag()
[!has[parent-tag]addprefix[error: ]addsuffix[ missing parent-tag]]
~[get[parent-tag]field:is-root-tag[yes]]
~[get[parent-tag]function[get.root.tag]]
\end

This looks at the current tiddler’s parent-tag, checks to see if it is a root tag, and if not it applies the same function to the parent-tag in a recursive way. The first filter run is there to handle the case where there is no parent-tag is found at some point in the tree.

\function currentRootTag()
[<currentTiddler>function[get.root.tag]]
\end

This is a shortcut notation I use to get the root tag of the current tiddler, which is useful to be able to call as a filter parameter

\function match.root.tag(tag)
[all[]]
:filter[function[get.root.tag]match<tag>]
\end

This is simply a single-operator way of filtering out tiddlers by whatever their root tag is.


What this then allows me to do, returning to the earlier example, is define a tree of locations within the world as a simple tag tree (ensuring that each tiddler also has a parent-tag field which points to its parent location), and then get a list of all locations within that tree by filtering using [match.root.tag[Locations]]. I can also safely tag other types of entity tiddler (e.g.characters or objects in the world) with location tiddlers to represent the fact that they are within those locations, but because each of them has a different parent-tag field, it isn’t caught up when filtering in this way.


I thought this approach might be interesting for others to see, but I also had some questions for anyone who is interested: Is this a sensible approach? Are there any issues I might not have anticipated? Is there an easier way to go about this?

Anyway, this was longer than I intended, but thanks for reading :smiley:

2 Likes