Proposal: TOC-macros Rewrite using IF, Functions and Procedures (+new fuctionality)

I think replacing the [all[shadows+tiddlers]tag<tag>!has[draft.of]$(sort)$] section in the toc-filters is against the nature of the TOC-macros. They are primarily tag based, because it’s easy to understand.

With the new toc-include field we only need 1 tag to start the mechanism. eg: root

Contacts → tagged: root … From there on you can entirely go with toc-include fields. As soon as users add an additional tag, the default behaviour kicks in – additionally.

  • I only intend this alternative for specific nodes found in the tag tree, I am not replacing the default behaviour, this is just how we code the filter to do what I am looking for.

I am not currently questioning this tag based toc.

However I have come across many cases where the use of recursion is raised because people are not satisfied with only tag based TOC’s;

  • Some of your own work like TocP illustrates this.
  • Sometimes they want a field based TOC or use an alternative tag field.

I have a knowledge based wiki containing a lot of plan language tiddler titles and currently use tags to organise them, I can drag the title from the TOC or a seperate index and drop the title onto any tiddler to tag it and thus including it in the toc/index.

  • As this gets larger I would prefer to move these into an alternative tags field and retain tags for high level subjects that do not participate in the TOC hierarchy.

This suggests to me - a generic hierarchical list macro

Once a revised TOC is in place, what ever its features, maybe the very next thing to do is to provide tiddlywiki with a “generic hierarchical list macro” that includes many of the features discussed here, but driven by any filter(s) which user chooses.

  • Although don’t get me wrong I really want these features in the built in TOC.

I could live with a new tagField macro parameter, similar to the one I did implement for the tag-picker macro, which is on halt atm. :confused:

I think the more functionality we add to the toc macros, the lower the possibility will be, to get it merged.

I did just push a new version

where all toc-macros should work now. If they do not work it’s probably a bug.

As some may know, I’m not a fan of “hidden information”.
So there are 2 new CSS classes assigned now, with which we can mark parents, that have hidden nodes.

  • toc-item-included … is assigned to every element, that comes from toc-include filter
  • toc-item-excluded … is assigned to a “parent” node, that has any hidden child-nodes defined by a filter in the parent

There’s some CSS inline STYLE to play with:

.toc-item-included  > a,
.toc-item-included > .tc-toc-caption
  color: green;

.toc-item-included > button > svg {
  fill: green;

.toc-item-excluded > a,
.toc-item-excluded > .tc-toc-caption
  color: red;

.toc-item-excluded  > button > svg {
  fill: red;

See here How to change the sort order of sub-branches in a TOC macro

Note the use of


With these proposed updates, would the drag and drop sorting still work? (Click on the parent tag pill, it lists its children, drag and drop them into order)

Maintaining order via fields etc is a nightmare as folders grow.

It’s super cool observing all the brainstorming around this topic!
Thank you soo much!

There is the preview: TiddlyWiki — a non-linear personal web notebook

The PR does not change the tag-pill macro. So they will still work unchanged.

Yes, that’s the question. We could use the code as follows. But that would remove all the elements that already tagged with an existing tag.

So if HelloThere would have a toc-include filter, all the existing elements would be removed. I’m not sure, if that’s what we want

	<$list filter=` [subfilter<tf.toc-include>]
					-[<tag>] -[subfilter<exclude>]`>

Latest Previews

toc-include will replace the existing filter
Preview as you suggested it:

toc-include will add elements to the existing tiddler
Preview as I suggested it:

1 Like

Thanks for this work! I am excited for expanded and more intuitive flexbility in tocs (especially, in my case, the tabbed variants).

Playing around a bit, it seems a bit surprising to me that the toc-include field and the toc-exclude field have very different behaviors:

The toc-include contains a list of tiddlers that act like “virtual children” of this tiddler, in any toc that already includes them. AND it overrides any existing tag-children (which may be a surprising result, for those who expect it only to append additional toc-children)

Meanwhile, the toc-exclude field does NOT specify a list of otherwise would-be toc-children that will now be included. Instead, if it is set to “yes”, that means “exclude ME from any toc that would otherwise include me” (as I’ve done with a tag-child of Second in screenshot below)

I see motivation for each of these behaviors (perhaps with the exception of letting toc-include totally displace whatever would be included by default), but the naming of these fields implies a kind of complementarity of function, while the reality is pretty different.

What I have below aren’t elegant field-names, but semantically it seems like there are three conceptual field-possibilities:

toc-include-here: [for naming or filtering-in virtual toc-children even though they’re not tagged (or otherwise included based on whatever an active toc-macro is looking for)]

toc-exclude-here [for naming or filtering-out toc-children that would be included based on a tag (or whatever an active toc-macro is looking for)]

toc-hide-me for an across-the-board easy way to get a tiddler to drop out of any toc that might otherwise try to include it.

Right now you seem to be using the first and the third of these conceptual possibilities, but they’re named in ways that would better fit the first and second.

There are 2 versions as seen at: Proposal: TOC-macros Rewrite using IF, Functions and Procedures (+new fuctionality) - #25 by pmario

The first one replaces the existing tags – The second one adds the new elements


The “additive” version is quick and intuitive… but if we don’t also have a toc-exclude at the parent, then one needs to go around modifying fields in children that one wants to exclude, and that might be difficult and/or not advisable (if the excluded tiddlers are part of packages that need not to be modified, etc.)

The “replacing” version is a cleaner logical approach, though the name “toc-include” would then be misleading; something like “toc-override” would be clearer, because now the filter condition can also exclude… To have it include the default tagged children PLUS additional ones (and maybe minus some default tagged child) is presumably not too difficult, right? I would just specify something like:

[tag<currentTiddler>] [[Virtual toc-child of First]] [[Another title NOT tagged with First]] -FirstOne

So, what do you think of toc-override as a field name?

1 Like

That would be a possibility. It’s also possible to add toc-override to the mix and have them all at the same time.

1 Like

So, last follow-up: if there is a toc-include field (perhaps in its additive version)…, and if there’s (also) some kind of toc-override (that can effectively use its filter to exclude as well), then what about using toc-hide (or something similar) rather than toc-exclude for the “leave-me-out” affordance — since the “exclude” seems (semantically) to promise to do the opposite of the “include” concept (that is, toc-exclude would seem to be another place to change how children of this toc-node would be handled, if that’s what toc-include does)?

@Springer … As the discussion is now, all your naming suggestion make sense. I’ll probably use them soon.


That’s great!

Your version wasn’t quite what I meant. But it showed me the way:

name: name-sort
tags: $:/tags/Global

\function  name-sort() "[{!!last-name}] [{!!first-name}] +[join[, ]]"
title: Person
caption: People
toc-include [tag[Person]sortsub:string<name-sort>] 

You can see this by downloading sorted-toc.json (2.2 KB), dragging it to pmario’s TOC fork, importing it, and opening TOC Test.

You’ll see in the “Sorted by (arbitrary) Title” section that the people are sorted by their Person/1, Person/2, … titles. But in the People section, they’re sorted by last name, and for those with the same last name, by first name. And that’s exactly what I was looking for.

I know there’s lots of testing to do, but I really look forward to this becoming part of the core!

Possible fields: toc-include, toc-override, toc-hide

Styles below can be used for testing with toc-selective-expandable

.toc-item-override> a,
.toc-item-override> .tc-toc-caption {
  color: darkblue;

.toc-item-override > button > svg {
  fill: darkblue;

.toc-item-included  > a,
.toc-item-included > .tc-toc-caption
  color: green;

.toc-item-included > button > svg {
  fill: green;

.toc-item-hide> a,
.toc-item-hide > .tc-toc-caption
  color: red;

.toc-item-hide> button > svg {
  fill: red;


<div class="tc-table-of-contents">
<<toc-selective-expandable "root">>

A designer may very well want to do this. For example to hide welcome messages and display learning content.

@pmario et al

It seems the conversation has continued overnight my time and I am now at a disadvantage. I am ill (chest cold) and needing to prioritise something else in my life, so I cant participate fully.

  • I am not in a position to review examples and respond to specific code.

I have being pursuing conditional tocs and custom child list within them, for a long time and included needs identified, in the forums over a number of years.

  • I will try and present this below a if it was the documentation for those missing features.

I will then have to leave it with you, and hope you use the ideas.

  • I think you can see how it would be easier to explain than other alternatives in this topic. However it does not rule out also introducing include/exclude options.

pho documentation

The TOC macros build a hierarchical tree based on an initial tag, and then lists those each title is “also tagging.” The results is a hierarchical list is like the Contents tab on The different TOC macros present this result in different ways.

In this proposed version it is possible to modify any tiddler that appears in such a hierarchy as follows;

  • add a toc-condition field to any tiddler in the tree, default fieldname fieldname toc-condition
    • The filter within this field should either return a single result or nothing.
    • If the field does not exist or is empty it will be ignored and the title will be listed.
    • If the field exists and returns any value the title will be displayed, if no value it will not be displayed.
  • add a toc-child-filter to any tiddler in the tree, default toc-child-filter.
    • The filter here will replace the standard listing of children below the current title.
      • If you want to list the items with the current tag, you need to add this back [tag<currentTiddler>].
    • This filter can be any filter generating zero or more items to list, It can contain additional conditions that determine what to list, including their sort order.
      • Is this where the TOC iteration stops?

The default TOC makes use of the above toc-condition and toc-child-filter (or by any other name) only if they appear in the tiddlers in the generated TOC.

  • When calling any TOC macro you can configure alternate fields that play the same roles as above toc-condition-fieldname and toc-child-filter
    • This permits multiple tag hierarchies to use different fields to implement these features even when the same title exists in multiple trees, just modify the fieldnames in the TOC macro parameters.
    • If you want to override the default behaviour modify the modify the TOC macro parameters to reference non-existent condition or child-filter fieldnames.

A desirable advanced feature (no need to change the tiddler itself)

The TOC macro could be enhanced further to do the following when testing for the named fields, to allow the custom fields to be provided without editing the current tiddler.

  • Does the fieldname(s) such as toc-condition or toc-child-filter exist in the current tiddler then make use of them
    • If the fieldname(s) such as toc-condition or toc-child-filter DO NOT exist in the current tiddler, then generate the title $:/config/toc/currentTiddler` and see if that tiddler contains //fieldname// and use that if it exists.
    • Other wise proceed as normal.
  • This allows the user or designer to override the TOC behaviour without editing the tiddler itself, by creating a tiddler containing the fieldnames to be used, if they exist.

I leave this now in the lap of the gods :smile: and return to feeling miserable

I think the whole thread is going to be a bit complicated to follow, due to the amount of filed-name changes.

I did some more testing yesterday and I’m going to change toc-overridetoc-filter

So I’ll close this thread here and I’ll create a new one, which hopefully does not need to change field-names again.

New: TOC-macros Rewrite using IF, Functions and Procedures (+new fuctionality) - Part 2

1 Like