So far I’ve come up with my custom drop-in solution:
const rootEl = dv.el("ul", "")
dv
.array(
input.rootNames.map(it => dv.page(it))
)
.forEach(it => renderNode(it, rootEl))
function renderNode(node, container) {
const liText = node?.path ?? node.file?.link
const liEl = dv.el("li", liText, { container })
const ulEl = dv.el("ul", "", { container: liEl })
dv.array(node[input.childrenKey])
?.map(it => dv.page(it))
.filter(it => !!it)
.forEach(it => renderNode(it, ulEl))
}
This is a custom view meaning that you have to create a separate .js
file and then connect it where needed:
await dv.view("dataviews/treeview", {
childrenKey: 'child',
rootNames: [
"File A",
"File B",
"File C"
]
});
- Here I decided to handpick roots (see the comment above about “cumbersomeness”)
- It is agnostic meaning that it expects those root names AND children key
Below are inputs and outputs of this view:
- Input (File Structure)
# File A
child:: [[C]]
# File B
child:: [[C]]
# File C
- Output (Generated List)
- A
- C
- B
- C
What to improve:
- It assumes that you don’t have circulars. It is sufficient for me, but be careful since it can end up with an infinite loop (and crash Obsidian). Add a depth variable if needed.
- It works with file names (
A
), not with file links ([[A]]
). I’m too lazy to figure out how to process links.