Hey there,
was playing a little with the new lua
integration after migrating to v2 and took the html / dom widget options for a spin. My goal was to create a reusable widget that consumes a page query and renders the result using styled html elements as a list. This allows to use it with any page query, in my case mainly targeting my index page for recently used notes. I also wanted to get familiar with space-lua
and maybe use this approach for other widgets (e.g. task lists) later so I tried keeping it modular. It should also be easy to adapt the code to your preferences as.
Each page is rendered with name, prefix, modification date and a list of tags. The full entry acts as a link that can be clicked to reach the page, and the tags are also clickable as in other areas of silverbullet.
I am new to lua
so feel free to leave feedback and ideas for improvements .
Screenshots
(desktop light, mobile dark)
Code Snippets
Lua code
```space-lua
widget = widget or {}
domElements = domElements or {}
function domElements.tagButtonRow(tags)
-- prepare tag list container
local tagsContainer = dom.span {
class="page-tags-container",
dom.b {"# "}
}
-- provide a fallback in case of no tags
if table.concat(tags) == "" then
local noTagsItem = dom.i {"no tags"}
tagsContainer.appendChild(noTagsItem)
end
-- add tags as clickable elements
for _, tag in ipairs(tags) do
local tagItem = dom.a {
class="sb-hashtag",
href="/tag:" .. tag,
rel="tag",
tag
}
tagsContainer.appendChild(tagItem)
end
return tagsContainer
end
function domElements.pageListEntry(page)
-- collect page info
local pagePrefix = (page.pageDecoration and page.pageDecoration.prefix or "")
local pageName = pagePrefix .. page.name
local pageModified = page.lastModified
local pageTags = page.tags
-- assemble page list entries
return dom.a {
href=page.ref,
class="page-list-entry",
dom.div {
class="page-name",
pageName
},
domElements.tagButtonRow(pageTags),
dom.span {
class="page-modified",
pageModified
},
}
end
function widget.pageList(pageQuery)
-- prepare list container element
local pageList = dom.div {
class="page-list"
}
-- add entry for each page
for _, page in ipairs(pageQuery) do
local pageListEntry = domElements.pageListEntry(page)
pageList.appendChild(pageListEntry)
end
-- render as html
return widget.html(pageList)
end
```
Styling
```space-style
.page-list {
border-radius: 12px;
box-shadow: 0px 0px 2px grey;
}
.page-list-entry {
text-decoration: none;
color: inherit;
display: block;
margin-left: 1rem;
margin-right: 1rem;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
border-bottom-color: #00000022;
border-bottom-style: solid;
border-bottom-width: 2px;
}
.page-list-entry:last-child {
border-bottom-style: none;
}
.page-list-entry .page-modified {
color: grey;
font-size: 0.8rem;
}
.page-tags-container {
display: flex;
margin-top: 0.2rem;
gap: 0.5rem;
font-size: 0.8rem;
vertical-align: middle;
color: lightgrey;
}
```
Usage
${widget.pageList(query[[from index.tag "page" limit 10]])}