2026-10-14 Showing a directory tree in Oddμ ============================================ I was wondering about offering people a way to leave Obsidian. Obsidian is, according to Wikipedia, "a proprietary personal knowledge base and note-taking application that operates on Markdown files." And Oddμ "helps you run a minimal wiki, blog, digital garden, memex or Zettelkasten … with Markdown files" -- so we're all set, right? Not quite. For one, Oddμ follows a few conventions: If you visit a directory, you're redirected to the index page. If that page does not exist, you're redirected to the edit action for the index page. You never get an overview of where all the other pages are, no sidebar to show all the pages. I wanted to fix this. The way to add interesting things to Oddμ is by writing code that gets called by the templates used. When looking at a page, the "view.html" template is used. The data it gets is a Page. When you read the oddmu-templates(5) man page, you'll see what you do with it. It's "attributes" are either fields of the Page structure, or functions. I wrote a new function called Tree which produces a linked list representing the directory, and some CSS to make it look like a directory tree as you might get it from tree(1). Skip Home Changes Edit Add Diff Zip Upload Search: Go . Vault * Oddμ: A minimal wiki * Welcome to Oddμ * themes * chat * 2026-04-28 * 2026-04-28 * Home * Themes * vault * 👉 Home **** Home **** The vault theme is for medium size wikis: between twenty and two hundred pages, perhaps. It shows a tree of all the existing pages in a sidebar. It’s good to have an overview over the directory structure and not having to write index pages everywhere. (If you’ve read enough, go back up to themes.) Comments? Send mail to Your Name < you@example.org > The Tree data structure is a link and possibly children for the link. The problem is, of course, that a directory is not really a page. What the code does, in this situation, is it links to the index page of the directory and gives it the name of the directory. At the end of the list above, for example, "vault" is a link with the name "index" and the title "vault" and it's only child is a link with the name "index" and the title "Home". Both link, in fact, to the same page. I know it's confusing but it looks pretty intuitive until you start clicking on directory names. type Link struct { Title string URL string } type Tree struct { Link Here bool Children []*Tree } The recursive nav template to produce the HTML, reformatted for readability, is shown below. Here is what it does: * if there is a link (the root node has no URL to link to) and if this is the link to the current page you're looking at, use an emoji and the title, but don't link to it; * otherwise link to the page and use its title for the link text (not the file name); * if it has children, start a new list and call the nav template for every link (start at the top); * if there is no link (that is we're at the root node), skip it, start a new list and call the nav template for every link (start at the top). The CSS to generate the nice lines is shown next. * navigation (nav) and page content (main) are both in a div with flex display, putting them next to each other; * the navigation gets a minimum width as well as padding, border and margin on the right; * the list marker is not shown but there is an indent of 2ex; * instead, the invisible pseudo-element before the list item (except for the top ones) get a border to the left and at the bottom (an L shape) but it's bottom is half a letter from the bottom (in the middle) and it's top is 50 lines up (this will fail for very long lists), and the overflow is hidden so you can't see the very, very long stem of the L (giving us the nice corner ┗ ) stretching up. The CSS is a wonderful idea I got from StackOverflow. div { display: flex } nav { padding-right: 1ch; margin-right: 1ch; border-right: 1px solid #eee; font-size: small } nav { min-width: 20ch } nav p { margin-bottom: 0 } ul.tree { list-style: none; margin: 0; padding-left: 2ex; overflow: hidden; } ul.tree li { position: relative; } ul.tree:not(.top-level) li::before { content: ''; position: absolute; border-left: 2px solid #888; border-bottom: 2px solid #888; right: calc(100% + .25ex); top: -5000%; /* 50 lines of skipping upwards */ width: 1ex; bottom: calc(100% - 0.5rem); } #Oddμ #CSS 2026-10-20. For an example of why this doesn't scale, take a look at this page, where you'll see the "vault" theme applied to this blog, with thousands of pages at the top level. It just doesn't work. You need something to open and close, like a hierarchy of DETAILS and SUMMARY elements; or some sort of solution that shows the immediate siblings, children, and a trail of ancestors. This would be possible, since I have implemented the functions, but I haven't actually tried it. Let me know if you have a better idea.