I’ve started self-hosting SilverBullet for a week and I’m shocked by its flexibility which allows be to organize my KB that I’ve never thought it’s possible. Very lightweight but packed with powers.
I’m currently experimenting with Query system and/or Widgets that would allow be to query a tag and then format its output with simple styling. Here’s the markdown file demonstrating what I’m trying to achieve (with emphasis on List Query section):
# Data
- One [mode: hot]
- Two [mode: cool]
- Three [mode: hot]
- Four [mode: hot]
# List Query
${template.each(query[[
from index.tag "item"
where _.page == editor.getCurrentPage()
order by _.name
]], template.new [==[
- ${_.name} with mode ${redText(_.mode)}
]==])}
# Widget: Red Text
```space-lua
function redText(text)
return widget.html(dom.span {
style = "color: red; font-weight: bold;",
text,
})
end
```
${redText [[ This is red text ]]}
What I expected from the code above under the section List Query is a list where each item is followed by a stylized red bold text of one of its attributes (e.g. mode). However, the actual rendering appears more like the following:
- Four with mode {html = {}, _isWidget = true}
- One with mode {html = {}, _isWidget = true}
- Three with mode {html = {}, _isWidget = true}
- Two with mode {html = {}, _isWidget = true}
Perhaps using Widgets is the wrong way to approach this. But I couldn’t figure out the way around this. Any pointers would be appreciated.
it’s a known bug, which is very hard to fix due to the working engine behind the widgets.
Check this github post out for further details:
If you are using the latest v2.2.1 silverbullet you can use the htmlBlock widget to create your own DOM table or other html elements, which lets you add formating and other DOM elements in your query tables:
I used this for my Manage Silverbullet Library table:
check out the “Build DOM Table to accept buttons (Function)” in my script for further details on how to use it.
after you created your DOM span elements you can simply format them with space-style, like i formated the buttons, make sure you give them unique id’s or classes so you can easily select them in the css.
# Data
- One [mode: warm]
- Two [mode: cool]
- Three [mode: hot]
- Four [mode: hot]
function buildList(q)
local items = {}
local function modeColor(mode)
if mode == "hot" then
return "red"
elseif mode == "cool" then
return "blue"
elseif mode == "warm" then
return "orange"
else
return "black"
end
end
for r in q do
table.insert(items,
dom.div {
style = "margin-bottom: 4px;",
dom.span { r.name .. " with mode " },
dom.span {
style = "color: " .. modeColor(r.mode) .. "; font-weight: bold;",
r.mode
}
}
)
end
return widget.htmlBlock(dom.div {
style = "font-family: sans-serif; font-size: 14px;",
table.unpack(items)
})
end
then just use:
-- Example usage:
${buildList(query[[
from index.tag "item"
where _.page == editor.getCurrentPage()
order by _.name
]])}
of course it could use some styling..but at least it works
[EDIT]: or this if you still want to maintain the list element:
function buildList(q)
local items = {}
local function modeColor(mode)
if mode == "hot" then
return "red"
elseif mode == "cool" then
return "blue"
elseif mode == "warm" then
return "orange"
else
return "black"
end
end
for r in q do
table.insert(items,
dom.li {
r.name .. " with mode ",
dom.span {
style = "color: " .. modeColor(r.mode) .. "; font-weight: bold;",
r.mode
}
}
)
end
return widget.htmlBlock(dom.ul {
-- style = "font-family: sans-serif; font-size: 24px; list-style-type: disc; padding-left: 20px;",
table.unpack(items)
})
end