Obsidian Plugins

Useful plugins for Obsidian.md

TOC

Plugins

Dataview

Dataview is now (more or less) deprecated by the Bases core plugin. While it still has its stronger features, Bases are so much faster (and safer).

Docs

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 operationsa1: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

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

Github
Docs or Docs

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