I want to be able to re-arrange my wiki’s table of contents like a drag-and-drop list. I understand there is a widget for something like this, but I don’t know how to combine it with the table of contents macro. Does anyone know the best way to get that to work?
Click on the tag pill for whatever tag you use for the root of the TOC (perhaps TableOfContents
). It will show a vertical list of tiddlers in that tag, which you can drag around as you please. You can do that for any level of the hierarchy. Nice and simple.
Breaking it up in that weird way is somewhat what I wanted to avoid and why I asked. You would need to grab the tag pill for every level you wanted to edit.
I’ve modified the toc macros on various occasions for various reasons. Like TWOutlier and a searchable TOC. Dragging and dropping is a pretty cool idea, but I think it would take two or 3 days coding. An easier hack would be to put a set of control buttons on each entree, allowing you to quickly move an item up or down the hierarchy. The controls could be hidden when not needed. Or you can just use a tag pill like Scott has suggested.
Remember what the TOC macro is: a way to show links to all the tiddlers with a given tag, and recursively also nest those tagged with those titles, and so forth. You can achieve this in several other ways, but I don’t think any are easier. One option is the list-before
and list-after
fields for individual menu tiddlers. The other is the list
field on the tag tiddler.
It’s easy enough to imagine a different TOC mechanism, perhaps a JSON tiddler that captures the hierarchy and a drag-and-drop editor that allows you to move these around. But that would take some investment of time, and lose the flexibility to alter the menu just by adding and removing tags.
Complex Wikitext isn’t my favorite, (and desperately needs syntax highlighting. Might be a future project), but I think I might just dig in and go for it with the macro. It can’t be too bad, right…
First things first. … For tiddlywiki.com there is a very high chance, that a custom sort order will not be approved by Jeremy. I did want to change the sort order several times and it got rejected for consistency reasons. TW uses alphabetical sort order. period.
Back to the OP.
@EricShulman … Do you have a drag & drop TOC?
First I thought, it would be insane. But after some more thoughts, I think it may be doable. But the initial UX may be a bit strange.
The toc-macros use an internal toc-caption macro. It would be possible to redefine it and wrap a link-catcher around it. It may need a configuration and toggling
So instead of opening the tiddler with a click it may be possible to show the tag-pill dropdown instead. Which is already drag and droppable.
But now there is the big But
There are some problems though.
- In the right sidebar there is always a “space problem” with dropdowns.
- As Scott wrote
- If tiddlers have a
list-before
orlist-after
field, those fields are removed if the sort order is defined with a list-field. - So there may be new tiddler timestamps after drag & drop actions, which may or may not be expected / wanted
- If tiddlers have a
- There may be tags, that have no physical tag-tiddlers
- As soon as drag and drop is used they will be created.
- This may have side effects
- Tag tiddlers may be shadows, which will become system tiddlers
- There needs to be some rules what should happen there
- Converting shadows to system tiddlers may cause update problems
- With the tag-pill dropdown, it’s not possible to drag and drop tiddlers to a different hierarchy out of the box
- So they would have to have the same tag
- That’s a limitation, that will be complained by users at the same day the function would be released. … Trust me
- Tiddlers may have 2 or more tags.
- At the moment the one that happens to be the first one in the list will be used
- This order is unpredictable and cannot be influenced in a reliable way.
- If the order changes the tree structure will change.
- With dynamic lists that’s not a problem.
- With custom order it will be a big problem
- ouch … this one may even make it impossible
- At the moment the one that happens to be the first one in the list will be used
- There are 5 different toc-macros that all share 60%+ code with each other
- So heavy and time consuming testing for unwanted side effects is needed
- And there may be other side effects, that I don’t even see atm.
…
So as Mark wrote. To get it finished in a generic way, time will add up very quickly. The base function will probably be fast. But the last 20% will be the crux.
I personally would start with a plugin. Because to get it ready for the core we probably talk about a week or more, taking all the edge cases into account, I did list above. … For the core those problems have to be solved. …
For a 3rd party plugin authors don’t have to care about all of them.
just some thoughs
no promises
no time
If I was making this a true plugin (or trying to get this in core), I would have to worry a lot more about most of those issues. My use case might sidestep those issues. I think I might just throw together a macro and put it here. I’m not super confident in wikitext, so I wouldn’t trust myself to make a non-js plugin anyway.
Here’s a trick which combines tag-pills with TOC to allow you to quickly access and rearrange items at any particular level (sadly not between levels)
Be sure to have a backup.
Put this at the top of your tiddler that has your TOC macro:
\define toc-caption()
\whitespace trim
<span class="tc-toc-caption">
<$set name="tv-wikilinks" value="no">
<$transclude field="caption">
<$view field="title"/>
</$transclude>
</$set>
</span> <<tag>>
\end
This locally overwrites part of the TOC macro.
Now each item will have a tag-pill after it. You can click on the tag pill and re-arrange items that are tagged by that tag.
You can change \define to \xdefine when you don’t want to see the pills (there are more elegant solutions I’m sure).
As I wrote. I would start with the toc-caption macro at: https://tiddlywiki.com/#%24%3A%2Fcore%2Fmacros%2Ftoc … which happens to be the first one you see if you open the link.
Redefining it would be straight forward. Then the link-catcher may be used to open the dropdown.
I think that would be a start.
-m
I got something simple working surprisingly easily. The remaining issue is that tiddlywiki seems to dislike nested drag and drops and everything goes to the parent droppable. Does anyone know a way around that?
Sure do! Just copy https://tiddlytools.com/#TiddlyTools%2FTOC
Then, use <<toc-tree TableOfContents>>
instead of the TWCore <<toc TableOfContents>>
. Note that “TableOfContents” is the name of the “root tag” for the tree. Of course, you can specify any tag you like.
To re-arrange the TOC items, just drag-and-drop an item. There are three drop options, controlled by modifier keys:
- no modifier = drop INTO (makes the dragged item a “child” of the current item)
- ctrl = drop BEFORE (makes the dragged item a sibling before the current item)
- shift = drop AFTER (makes the dragged item a sibling after the current item)
Note: you can also ADD new items to a tree using drag-and-drop. Just grab any draggable tiddler title (e.g., from one of the Sidebar lists), and drop it onto a tree item. Modifier keys can be used as described above to drop INTO, BEFORE, or AFTER the current tree item.
In addition to the drag and drop handling, the toc-tree
macro does “mouseover” highlighting to make it easier to see which item you are dropping onto, and “current tiddler” highlighting to show you the $:/HistoryList!!current-tiddler
(assuming its in the tree, of course).
The optional max
parameter lets you limit the depth of the tree (e.g., max=3
will only display three levels deep).
The optional field
parameter lets you use an alternative field other than tags
to define the tree structure; e.g., field:parent
will render a tree just like Mario’s <<tocp>>
macro.
The <<toc-tree>>
macro also adds “auto-open” handling, so that if you use a regular link to navigate from one tiddler to another, the tree will automatically open the corresponding branch and apply “current tiddler highlighting” in the tree display.
You can also define a separate “template” tiddler named TiddlyTools/TOC/ItemTemplate
to render additional custom output for each tree item. For example, https://tiddlytools.com/#TiddlyTools%2FTOC%2FItemTemplate adds the tiddler toolbar “more” menu to each item, as well as displaying the tiddlers icon
field image (if any) next to the item title.
There are also a few extra TOC-related macros:
-
<<toc-all TableOfContents>>
will output the entire tree, fully expanded. -
<<toc-list TableOfContents>>
will output the entire tree as a “flat list” of tiddler titles.
I’m somewhat amazed you have this laying around, but it works great. Thanks a ton. Stuff like this does make me wish this was all more centralized. Though I guess these forum posts create a great record of them.
In more than a decade with TiddlyWiki I have seen similar requests many times, the core TOC macros are designed to be robust, including avoiding infinite loops, but can be hard to manipulate and using a different macro makes sense, if you are interested have a look at discussions about recursive macros.
I do however feel as a community we could develop a solution that is even more customisable and while your mind is on this subject please consider this enhancement, that could solve a suit of customisation requirements; I hope others may have more ideas.
For example;
Enhance or replace the TOC macros such that the children of any item in that TOC (a node) is determined from the initial filter (as current) unless a child-filter is present in that node, which will be used instead, and an optional alternative list item template so the way such items are rendered can be altered.
- Instead of the above or alongside it, perhaps a macro name could be given to handle the children, allowing any method to list children, be able to be used from any node in the hierarchy, with a simple override.
- Such a macro or filter can apply custom sort orders or even start a new TOC on any node, even starting with the root node.
- One could even list outstanding todo items with checkboxes under any node as an example, or make urls in a given node clickable.
Deeper issues
- An option to allow a custom child filter to be used for all subsequent levels or just the children of the current node would be wise, because then we can choose the filter will be inherited or not.
- Allowing any tiddler (you may use in a TOC to also have an optional display-filter that is tested (if it exists) before display in the TOC, would allow parts of a toc (starting with that node) to be concealed unless a condition is met eg
[{$:/config/design-mode}match[yes]]
- I would like to see this display-filter method deployed in the tabs macro as well so tabs can be optional depending on a condition, or even in other tag driven display mechanisiums such a view and edit template items, toolbar buttons etc…
So all I propose here is a TOC with customisable children.