[TW5] Breadcrumbs needed

260 views
Skip to first unread message

Hegart Dmishiv

unread,
Dec 29, 2015, 11:17:10 PM12/29/15
to tiddl...@googlegroups.com
Hi all, I'm back working on my TiddlyWiki implementation, trying to get all the content I need prepared before the release party / installfest for Lubuntu 16.04 LTS is released in April 2016.

I've made some good strides using the TOC and <<toc-expandable >> feature to display the sub-types / sub-categories on my tiddlers. Now I want to display parent-types / parent-categories as well, for ease of navigation, and I think a breadcrumb trail would be helpful for this. I've had a look at Ton Gerner's solution, but the fixed, non-scrolling screen position of it doesn't appeal to me. I've also briefly viewed @Tobi's discussion about the NameSpaceWidget.

I'd just like a simple breadcrumb list at the top of the tiddler. It would need to be smart enough to abbreviate itself for deep levels of links, say, more than three levels of parents. For example, something like this....


Is there some simple way to do this in TW5 already, utilising the TOC system? I see that @Eric had created a breadcrumb plugin for TWC, but I'm not sure how to implement such a feature in TW5. Thanks in advance for any help offered.

Jed Carty

unread,
Dec 30, 2015, 2:39:44 AM12/30/15
to TiddlyWiki
While it isn't perfect this does the first part (the order is reversed compared to what you have, I am not sure how to fix that)

Make a tiddler called whatever you want, tag that tiddler with $:/tags/ViewTemplate and put this in the text field:

\define breadcrumbs()
<$list filter='[is[current]tags[]]-[[$:/tags/SideBar]]' emptyMessage='<br>'>
 
< <$link to=<<currentTiddler>>><$view field='title'/></$link>
<<recursiveFilter>>
</$list>
\end

<<breadcrumbs>>

make a field called list-before and put $:/core/ui/ViewTemplate/title in that field. Save the tiddler and then every tiddler should have the every path up the tags tree from that tiddler listed.

Unfortuantely it is in the form
< tiddler 3 < tiddler 2 < tiddler 1 < home

To make it truncate the results may take a bit more thought. I will look at it.

Jed Carty

unread,
Dec 30, 2015, 2:41:10 AM12/30/15
to TiddlyWiki
Sorry, I messed up with the copy-paste in that last post, the code should be:

\define breadcrumbs()
<$list filter='[is[current]tags[]]-[[$:/tags/SideBar]]' emptyMessage='<br>'>
 
< <$link to=<<currentTiddler>>><$view field='title'/></$link>
<<breadcrumbs>>
</$list>
\end

<<breadcrumbs>>


Hegart Dmishiv

unread,
Dec 30, 2015, 3:27:28 AM12/30/15
to TiddlyWiki
Thanks for the replies @Jed. In fact, you're right, the arrows should point to the left, going back up the structure of parents. I have implemented your suggestion on my dev instance, now I'll go and do likewise on my live (offline) TW5 wiki. Again, thanks for your help on this.

Hegart.

Matabele

unread,
Dec 30, 2015, 3:27:56 AM12/30/15
to TiddlyWiki
Hi Jed

Clever :-) Gives me other ideas.

regards

Hegart Dmishiv

unread,
Dec 30, 2015, 3:40:29 AM12/30/15
to TiddlyWiki
Right, I've got it working in my live (offline) TW5 implementation now, and I can see the problem with it that you were talking about, Jed. It's not just the direction of the angle brackets, is it? The entire structure is listed in the wrong direction. With a hierarchy of foo as the topmost level, then bar under it, and baz as a sub-level under bar, it should be....

foo < bar < baz

...but what we have at the moment is...

baz < bar < foo

...which puts the top-most parent at the far right, instead of the far left end. Any ideas how to fix this?


Hegart.

On Wednesday, 30 December 2015 20:41:10 UTC+13, Jed Carty wrote:

Jed Carty

unread,
Dec 30, 2015, 3:41:33 AM12/30/15
to TiddlyWiki
Ok, this should do everything you want. Give it the same stuff as before (tagged with $:/tags/ViewTemplate and the field list-before with the contents $:/core/ui/ViewTemplate/title)

\define again()
<$list filter=<<First>>><$link to=<<currentTiddler>>><$view field='title'/></$link> > </$list>
<$list filter=<<Extra>> emptyMessage=''>... > </
$list>
<$list filter=<<End>>><$link to=<<currentTiddler>>><$view field='title'/></$link> > </$list>
\end

\define finalFilter()
<$set name=First filter='$(TheFilter)$ +[last[]]'>
<$set name=End filter='$(TheFilter)$ +[butlast[]]  +[butfirst[]] +[first[3]] +[reverse[]]'>
<$set name=Extra filter='$(TheFilter)$ +[butlast[]] +[butfirst[]] +[butfirst[3]] +[limit[1]]' emptyValue='[is[system]!is[system]]'>
<<again>>
</
$set>
</$set>
</
$set>
\end

\define breadcrumbs()
<$list filter='[is[current]tags[]]-[[$:/tags/SideBar]]' emptyMessage='<br><<finalFilter>>'>
<$set name=TheFilter filter='$(TheFilter)$ [<currentTiddler>]'>
<<breadcrumbs>>
</$set>
</
$list>
\end

<$set name=TheFilter filter='[is[current]]'>
<<breadcrumbs>>
</$set>


Jed Carty

unread,
Dec 30, 2015, 3:53:41 AM12/30/15
to TiddlyWiki
Ok, I like this enough to put it on my site, so you can copy the tiddler from here if you want.

Hegart Dmishiv

unread,
Dec 30, 2015, 4:00:57 AM12/30/15
to TiddlyWiki
Hey thanks, I've just put that code straight into my live (offline) TW5 instance and it works much as i had requested originally, even the truncation of deep levels, using an ellipsis. That's awesome!

However, I have created a further problem for myself, in that the macro processes ALL tags on a tiddler, and all tags on the parent tiddlers. In a straight line, single tag-per-tiddler arrangement, this works fine. But when there is more than one tag on a tiddler (such as the additional "stub" tag in the example below), there are multiple breadcrumb lines displayed.

Jed Carty

unread,
Dec 30, 2015, 4:18:27 AM12/30/15
to TiddlyWiki
If you know what your apex tag is and only want paths that lead to that than I could set that up, but if you have multiple paths that lead to it than every one will be displayed. The only way I can think of to get around that is to just have it pick the first path. On my side I added the option to collapse the list so large lists don't take up too much space. I may combine the two where the first path is shown by default and you can expand it to show all paths if you wish.

Hegart Dmishiv

unread,
Dec 30, 2015, 4:26:17 AM12/30/15
to TiddlyWiki
That two-pronged approach sounds like the answer. I'll grab a copy from your site when you've got it working. Thanks. One day I'll have to sit down and work out how you did that, but for now I'm just getting back into using TiddlyWiki after a few months break, and having to re-learn much of what I learned when I first started using it, teeheehee.

Jed Carty

unread,
Dec 30, 2015, 5:22:40 AM12/30/15
to TiddlyWiki
Ok, I am happy with how it is now. You can set the apex tag you want and have it only display paths that start with that tag (so in your image you could use Contents and only the path to Contents would be shown). It will still show all paths to that tag but I don't think that case will come up too often. Either way, I am not sure how to change that.

All the settings are in fields of the template tiddler, but I put a way to change them into the Other Tweaks tab of my control panel. Here is the finished version. http://inmysocks.tiddlyspot.com/#Tiddler%20Breadcrumbs%20Template

Hegart Dmishiv

unread,
Dec 30, 2015, 6:33:35 AM12/30/15
to tiddl...@googlegroups.com
Okay, I've got that now in my dev TW5 instance, thanks. I've also copied a very simplified tag structure from my live (offline) TiddlyWiki to dev. The structure there is currently only a single-tag-per-tiddler straight line, making your macro work perfectly as intended. Adding extra tags to a tiddler anywhere in the structure causes problems still.

By the way, thanks for all the help. It has prompted me to re-learn how to use Prose.io and Travis CI to update my dev instance on GitHub, which I hadn't done for a while. The grey matter is getting a good work out tonight. :-)

EDIT: It's okay, I found the problem. You had hard-coded the name of the tiddler within the code, even though your initial instruction to me was

Make a tiddler called whatever you want...

Haha, I'm not a programmer really, but I can spot such things (eventually). Looks like it is working fine for me now that I have replaced the hard-coded tiddler title. Thanks again.

Hegart.

Matabele

unread,
Dec 30, 2015, 7:24:21 AM12/30/15
to tiddl...@googlegroups.com
Hi

You may wish to play around with a CSS stylesheet.

1. Place this code into a stylesheet (tagged $:/tags/Stylesheet)

.breadcrumb {
    list-style: none;
    overflow: hidden;
    margin-left: -30px;
    margin-top: -30px;
}
.breadcrumb li {
    background: #F6F6F6;
    padding: 2px 0 2px 36px;
    background: #F6F6F6;
    position: relative;
    display: block;
    float: left;
}
.breadcrumb li:before {
    content:" ";
    display: block;
    width: 0;
    height: 0;
    border-top: 11px solid transparent;
    border-bottom: 11px solid transparent;
    border-left: 20px solid #ffffff;
    position: absolute;
    top: 110%;
    margin-top: -25px;
    margin-left: 1px;
    left: 100%;
    z-index: 1;
}
.breadcrumb li:after {
    content:" ";
    display: block;
    width: 0;
    height: 0;
    border-top: 11px solid transparent;
    border-bottom: 11px solid transparent;
    border-left: 20px solid #F6F6F6;
    position: absolute;
    top: 110%;
    margin-top: -25px;
    left: 100%;
    z-index: 2;
}

2. Mark up Jed's code like this:

\define again()
<ul class="breadcrumb">
<$list filter=<<First>>><li><$link to=<<currentTiddler>>><$view field='title'/></$link></li></$list>
<$list filter=<<Extra>> emptyMessage=''><li>...</li></$list>
<$list filter=<<End>>><li><$link to=<<currentTiddler>>><$view field='title'/></$link></li></$list>
</ul>

\end

\define finalFilter()
<$set name=First filter='$(TheFilter)$ +[last[]]'>
<$set name=End filter='$(TheFilter)$ +[butlast[]]  +[butfirst[]] +[first[3]] +[reverse[]]'>
<$set name=Extra filter='$(TheFilter)$ +[butlast[]] +[butfirst[]] +[butfirst[3]] +[limit[1]]' emptyValue='[is[system]!is[system]]'>
<<again>>
</$set>
</
$set>
</$set>
\end

\define breadcrumbs()
<$list filter='[is[current]tags[]]-[[$:/tags/SideBar]]' emptyMessage='<br><<finalFilter>>'>
<$set name=TheFilter filter='$(TheFilter)$ [<currentTiddler>]'>
<<breadcrumbs>>
</
$set>
<
/$list>
\end

<$set name=TheFilter filter=<<currentTiddler>>>
<<breadcrumbs>>

</$set>


Works OK for single lines -- confused for multiple lines. Anyway, it's a start.

regards

Matabele

unread,
Dec 30, 2015, 7:35:29 AM12/30/15
to TiddlyWiki
Hi

I made a small change to the markup, which works better. A demo of the resulting breadcrumbs may be seen here.

You need to copy over two tiddlers: $:/Breadcrumbs and $:/Stylesheet/crumbs

regards

On Wednesday, 30 December 2015 06:17:10 UTC+2, Hegart Dmishiv wrote:

Matabele

unread,
Dec 30, 2015, 8:00:19 AM12/30/15
to TiddlyWiki
Hi

Looks a little better with a spacing of 2px between each crumb.

regards

Jed Carty

unread,
Dec 30, 2015, 9:43:47 AM12/30/15
to TiddlyWiki
I ran into a rather serious problem with recursion. The same thing as when you have a loop in a toc macro. Luckly it should be fixed in the newest version. Considering that it will lock up your wiki whenever you open a tiddler that is tagged in a way that causes a problem I suggest you update what you have. Unfortunately this means that the styling Matabele made will need to be updated.

If you run into any other errors let me know.

Also, it may be possible to use a similar fix on the toc macros to prevent the recursion errors but I am not sure, the toc macros are quite a bit more complex.

Matabele

unread,
Dec 30, 2015, 10:12:44 AM12/30/15
to TiddlyWiki
Hi Jed

Wouldn't limit[] operators help?

\define breadcrumbs()
<$list filter='[is[current]tags[]limit[7]]-[[$:/tags/SideBar]]' emptyMessage='<br><<finalFilter>>'>

<$set name=TheFilter filter='$(TheFilter)$ [<currentTiddler>]'>
<<breadcrumbs>>
</$set>
</
$list>
\end

regards

Matabele

unread,
Dec 30, 2015, 10:23:19 AM12/30/15
to TiddlyWiki
Hi Jed

Nope -- still locks with circular references (old version). I tested with two tiddlers each tagged with the others title

regards

On Wednesday, 30 December 2015 16:43:47 UTC+2, Jed Carty wrote:

Jed Carty

unread,
Dec 30, 2015, 10:34:29 AM12/30/15
to TiddlyWiki
I just put up a new version that I haven't been able to break yet. It may keep some things from showing up correctly but I haven't found any yet.

Eric Shulman

unread,
Dec 30, 2015, 11:41:52 AM12/30/15
to TiddlyWiki
On Wednesday, December 30, 2015 at 7:34:29 AM UTC-8, Jed Carty wrote:
I just put up a new version that I haven't been able to break yet. It may keep some things from showing up correctly but I haven't found any yet.

As part of my InsideTiddlyWiki (ITW) book project, I've written my own TOC macro replacements with lots of good stuff, including a <<toc-path>> macro that handles all loops in the parent path.  Here's a simplified version of that function that illustrates the basic recursion for showing the path:

\define toc-path()
   
<$macrocall $name="toc-path-body" here=<<currentTiddler>>/>
\end
\define toc-path-body(here,exclude)
   <$list filter="""[title[$here$]tags[]] $exclude$ -[[$here$]] +[limit[1]]""">
      <$macrocall $name="toc-path-body" here=<<currentTiddler>> exclude="""$exclude$ -[[$here$]]"""/
>
     
<$link><$text text=<<currentTiddler>>/></$link> &gt;
   
</$list>
\end

Notes:
* I used [limit[1]] to handle the "multiple parents" issue.  It only shows the "first" path from the current tiddler to the root of the tree.
* The "exclude" param is not passed initially.  It is used internally to keep track of which tiddlers have already been visited in the path to avoid looping. This also means that if a node has two or more parents, the first parent not already excluded is used to continue up the tree.
* The recursion happens *before* the output.  Thus, the macro gets to the root of the tree, and THEN outputs the current title, followed by a ">" (&gt;).  As the recursion 'pops the stack', successive titles are displayed, giving the proper "top down" path from root to node.

enjoy,
-e


Matabele

unread,
Dec 30, 2015, 12:00:17 PM12/30/15
to tiddl...@googlegroups.com
Hi Eric

Nice :-) I added breadcrumb styling. Download the files attached and drop them onto your wiki.

Enjoy!
$Stylesheet-crumbs.tid
$crumbs.tid

Matabele

unread,
Dec 30, 2015, 12:35:19 PM12/30/15
to TiddlyWiki
Hi

A demo of the Eric's crumbs may be found here -- the required tiddlers: $:/crumbs and $:/Stylesheet/crumbs, can be dragged across from the System tab.

regards

Jed Carty

unread,
Dec 30, 2015, 12:38:55 PM12/30/15
to TiddlyWiki
I didn't use limit because I want to leave in all the paths, I just added the logic needed to prevent loops in a path by not listing the same tiddler twice in a single path. So if there are 2 paths to a tiddler through the toc it will show both of them.

Tobias Beer

unread,
Dec 30, 2015, 2:55:03 PM12/30/15
to TiddlyWiki
Hi Matabele,
 
Nope -- still locks with circular references (old version). I tested with two tiddlers each tagged with the others title

But this is literally circular logic and speaks of a poor model... that needs revision, if not fixing... although TiddlyWiki may have or provide ways of capturing this.

Best wishes,

Tobias.

Hegart Dmishiv

unread,
Dec 30, 2015, 3:07:07 PM12/30/15
to tiddl...@googlegroups.com
I'm definitely in favour of a single path, a single line of text for the breadcrumbs. Would a field on the regular tiddlers be useful to determine the specific parent, if more than one tag is present? I've seen other solutions on these forums now (having looked a lot more at this last night) which rely solely on a specific "parent" field on each tiddler, and build their breadcrumbs based on that field. That seems like a lot of extra work, particularly for those that only have a single parent tag, so some sort of filter that references the tiddler's "parent" field only if it exists, or if there is more than one tag, but that would then require a test for the presence of the "parent" field as well anyway.

Hegart.

Hegart Dmishiv

unread,
Dec 30, 2015, 3:30:48 PM12/30/15
to tiddl...@googlegroups.com
@Matabele, I really like your stylesheet example, thanks. I'm now using your latest one on my dev instance, but it doesn't seem to work for me. I copied the stylesheet (commit) and the breadcrumbs.tid file (commit) but they don't show up on my tiddlers. Where did I go wrong? The only thing I changed from yours was the tiddler titles, as I keep all my system tiddlers in folders prefixed with $:/_ so that I can find them easily. So I have $:/_Macros/breadcrumbs and $:/_Styles/breadcrumbs

Hegart Dmishiv

unread,
Dec 30, 2015, 5:54:37 PM12/30/15
to tiddl...@googlegroups.com
I went ahead and added your one to my live (offline) TW instance, Matabele, hoping it was just some weird GitHub issue that prevented it from working on my dev instance. But it's not working here either. I just have no breadcrumbs showing at all now. I already have a tiddler called $:/_Styles/stylesheet, and I was wondering if I should just copy your styles into that, as a global stylesheet. Would that help?

Matabele

unread,
Dec 30, 2015, 6:58:37 PM12/30/15
to TiddlyWiki
Hi Dmishiv

The listings with Eric's version differ from Jed's version. On the demo I put up, for example, there are no listings on many tiddlers which used to have listings (including the top two on my demo wiki.) The 'missing' listings seem to relate to links which, in Jed's version, did not correspond with a tiddler (clicking them brought up an empty tiddler.)

Anyway, on my demo, if you scroll down to the "ChecklistWidget" tiddler (or browse through the TOC) -- you should see breadcrumbs for those tiddlers appearing in the TOC.

Don't know exactly what the various listings correspond too -- I only added styling to the code. 

regards

Matabele

unread,
Dec 30, 2015, 7:12:25 PM12/30/15
to TiddlyWiki
Hi Hegart

Just visited your wiki -- you seem to have Jed's old version of the breadcrumb code -- I copied the tiddler $:/crumbs across to your wiki, and everything works.

I did not delete Jed's old version ($:/Breadcrumbs), but only removed the system tag $:/tags/ViewTemplate -- this is the version you appear to have copied across (therefore, no crumbs.)

Hope this solves your problem.

regards

On Thursday, 31 December 2015 00:54:37 UTC+2, Hegart Dmishiv wrote:

Hegart Dmishiv

unread,
Dec 30, 2015, 7:28:23 PM12/30/15
to TiddlyWiki
Aha, that makes sense now. I have it working at my end now, ta. Any idea how to limit your one to a maximum of 5 or so levels, and to trucate any parents above that with an ellipsis, apart from the root (eg. "Contents") tag, as Jed had? If we could get that working as well, this would be sweet!

Matabele

unread,
Dec 30, 2015, 7:37:37 PM12/30/15
to TiddlyWiki
Hi Hegart

This is Eric's code, not mine -- but I'll have a look to see what can be done.

regards
Reply all
Reply to author
Forward
0 new messages