I like to structure my pages in an hierarchical way and wanted to see the current nesting / “breadcrumbs”. I added a Template Widget and some space script for it, see below in case anyone else is interested. Happy to hear any comments or suggestions!
Nice! I ran into the same need and did a similar thing in space-lua before I discovered this solution.
Here it is for reference and comparison:
```space-lua
yg=yg or {}
function yg.breadcrumbs(path)
local mypage = path or editor.get_current_page()
local parts = string.split(mypage,"/")
local crumbs = {}
for i,part in ipairs(parts) do
local current = ""
for j=1,i do
if current != "" then current=current.."/" end
current = current..parts[j]
end
table.insert(crumbs, {name = current})
end
return crumbs
end
yg.t_bc = template.new([==[/[[${name}]]]==])
function yg.bc(path)
return "[[index|🏠]]"..(template.each(yg.breadcrumbs(path),yg.t_bc))
end
(I ran into problems withtable.concat() and unpack(), so the sub-path assembly is loopy)
Usage (should also work in templates/live widgets) :
${yg.bc()}
Raw table:
${yg.breadcrumbs()}
For a different path:
${ yg.bc("Milky Way/Solar System/Earth") }
```space-lua
yg=yg or {}
function yg.breadcrumbs(path)
local mypage = path or editor.getCurrentPage()
local parts = string.split(mypage,"/")
local crumbs = {}
for i,part in ipairs(parts) do
local current = ""
for j=1,i do
if current != "" then current=current.."/" end
current = current..parts[j]
end
table.insert(crumbs, {name = current})
end
return crumbs
end
yg.t_bc = template.new([==[/[[${name}]]]==])
function yg.bc(path)
return "[[index|🏠]]"..(template.each(yg.breadcrumbs(path),yg.t_bc))
end
But I have error message while calling the function ${yg.bc()} on my pages
Lua Error : Attempting to index a nil value
I’m sorry if this is obvious but lua is a bit confusing to me.
Edit : After resyncing /reloading / resetting the application and the client : It works
So other question : How this is possible to have this Breadcrumbs positioned above the menu and the frontmatter ?
yg.t_bc = template.new[==[/[[${name}]] ]==]
yg.t_bcsub = template.new[==[-[[${name}]] ]==]
function yg.breadcrumbs(path)
local mypage = path or editor.getCurrentPage()
local parts = string.split(mypage,"/")
local crumbs = {}
for i,part in ipairs(parts) do
local current = ""
for j=1,i do
if current ~= "" then
current=current.."/"
end
current = current..parts[j]
end
table.insert(crumbs, {name = current})
end
return crumbs
end
function yg.bc(path)
return "[[home]]"..(template.each(yg.breadcrumbs(path),yg.t_bc)).." "..(template.each(yg.children(path),yg.t_bcsub))
end
function compareDate(a, b)
print(a.lastModified > b.lastModified )
return a.lastModified > b.lastModified
end
function yg.children(path)
local crumbsChildren = {}
local mypage = path or editor.getCurrentPage()
for page in each(table.sort(space.listPages(), compareDate)) do
--print(mypage,page.name,string.find(page.name,mypage) )
if (string.find(page.name,mypage) and mypage ~= page.name and #crumbsChildren <7)
then
table.insert(crumbsChildren, {name = page.ref})
end
end
return crumbsChildren
end
parent and last 7 modified children are visible in breadcrumbs.
---
description: Adds breadcrumbs
tags: template
hooks.top:
where: 'not pageDecoration.disableTOC'
# Show all the way at the top
order: -1
---
${yg.bc()}
If those interested in breadcrumbs for v2 then you don’t need the template, but a widget definition and an event listener:
function widgets.breadcrumbs()
return widget.new {
markdown = yg.bc()
}
end
event.listen {
name = "hooks:renderTopWidgets",
run = function(e)
return widgets.breadcrumbs()
end
}
I’ve noticed that the breadcrumb widget “collides” with the table of contents.
This is because widgets by default are generated with the span html tag to make them inline well.
I’ve tried adding display = "block" to the widget definition, or even cssClasses but it seems to only work with the html widget - not the markdown one. @zef is this a correct/expected behavior? It sure is a bit confusing
As a terrible workaround (that works), to fix this add this space-style:
Right, the implementation is a bit limited right now. Effectively what happens is that the renderTop/BottomWidgets events are triggered, and all the HTML and markdown that those return are simply concatenated, block or css classes are ignored. I’d have to think how to do this differently.