Obsidian Plugins
Useful plugins for Obsidian.md
TOC
Links
Plugins
Dataview
Docs
Other links
- My DVJS bookmarks
- Complex structures via CustomJS plugin
- How to use Dataview outside a dataviewjs code block
- async & await in dataviewjs codeblock
- Code reuse
- Dataviewjs disappears in reading and preview mode
data: |
dataviewjs:
const loadData = async () => {
return dv.pages()
.groupBy(p => p.file.ctime.toFormat("HH"))
.map(p => ({cdate: p.key, count: p.rows.length}))
.array();
};
return await loadData();
Dynamic Tables with DataviewJS
Reusing Dataview queries
If I had a page called my script and put the DQL into a property called script, you can call it onto any page with just
$ =dv.execute(await dv.page("my script").script)
The this in the script will localise to the page it's called on, and if changes to the script it will naturally update everywhere, same as bases.
If the only thing your script page was, was the script, then you can also skip the property entirely. Just write it into a plain text file and call it the same sans the last .script.
CalcCraft
Have formulas in tables like in excel
GitHub
---
cssclasses: calccraft
---
a2+b2 // simple sum
-2c+1r // two columns left, one row down
-0c-1r // same column, 1 row up
(b-2r)-(b-1r)
[a:a] // map entire column to the result column
sum(b1:b-1r)
min(b2:b-1r)
max(b2:b-1r)
[b2:b99]-[c2:c99] // sub rows
sum(a2:b4) >20 // boolean
transpose([a2:c4]) // transpose matrix
range(1,20,2) // generate sequence
map([a:a],hex) // map function
map([a:a],sin)
map([a:a],isPrime)
isNumeric([a:a])
to(unit(a2), "cm") // unit conversion
[a:a]./[b:b] // 5 m | 10 s = 0.5 m/s
([b:b]-[a:a])./[c:c] // 10 km/h | 100 km/h | 10 s = 2.5 m/s^2
gravitationConstant
planckConstant
Use [a1:c3] for matrix operations, a1:c3 for simple ranges
Include units in your data - the plugin handles conversions automatically
Bases
See the Docs for a generous set of the Bases functions. Moreover, you have a lot more JS functions to use.
Various tricks
Cards images
- Create a new formula named thumbnail (or whatever more convenient)
- Set this formula name as Cards view's image property
I avoid creating a dedicated property with the image file name, instead I prefer to generate it using formulas.
A few tricks on generating those image links:
The simplest, if you name images next to the note's name:
file.name + '.jpg'
More advanced if you have mixed image formats. This will check if webp image file is available and if not, it will try jpg version.
file.name + if(file(file.name + '.webp'), '.webp', '.jpg')
It can be extended further for more variants by recursing the if function. And yes if is a function not a statement in the Bases world. Now it can find if there's a web, jpg on png image with the same name as the note.
file.name + if(file(file.name + '.webp'), '.webp', if(file(file.name + '.jpg'), '.jpg', '.png'))
Combining properties for more compact representation
Take the started and finished properties (dates) and create a readable interval to output in one-liner instead of two. See the JS's date and time formatting.
note.started.date().format('DD MMM') + ' - ' + note.finished.date().format('DD MMM')
Again to output more date in one table's line, combine the status (done, in progress...) with time track value:
note.status + ' 🕑 ' + note.timetrack
Let's combine all 4 of these together:
note.status + ': ' + note.started.date().format('DD MMM')+' - '+note.finished.date().format('DD MMM') + ' 🕑 '+note.timetrack
The status still takes more space than it deserves, let's replace it with emojis:
if(note.status = 'Done', '✅', '⏳') + ': ' + note.started.date().format('DD MMM') + ' - ' + note.finished.date().format('DD MMM') + ' 🕑 ' + note.timetrack
More examples
Convert a copied windows path into a clickable link. The folder property here contains a file/folder path simply copied from the Explorer. This little script converts it into URL, that you'll be able to click and open the file/folder right from Obsidian.
link('file:///' + note.folder.replace('\\', '/'), note.folder)
You can use images in the Table view as well. Just have to use the image() function to convert from filename. This script also checks if the file exists first, and if it doesn't, the script outputs 'No image yet' text instead.
if(file(file.name + '.jpg'), image(file.name + '.jpg'), 'No image yet')
Digital Garden
Free publishing alternative by Oleeskild via Netlify or Forestry
Styling
Any css/scss files placed under src/site/styles/user will automatically be linked into the head right after all other styling. Meaning that the styling added here will take presedence over everything else.
Custom fonts to /src/site/styles/user/fonts
CSS snippets go to src/site/styles/user/
Fonts passthrough to add to /src/helpers/userSetup.js
function userEleventySetup(eleventyConfig) {
eleventyConfig.addPassthroughCopy("src/site/styles/user/fonts/*");
Favicon
SVG only and must be exactly square, otherwise Netlify will fail to deploy the entire build!
CSS snippets
MCL
CSS Layout hack for Obsidian
Docs
Callout grid
https://forum.obsidian.md/t/css-snippet-to-display-markdown-in-grids-without-html/95117