In questo articolo vorrei descrivere la mia esperienza con Obsidian includendo alcuni consigli che possono aiutarti a trasformare il tuo Obsidian nel miglior sistema per prendere note mai visto. A partire da un semplice documento di testo scritto in markdown è possibile creare un vero e proprio database in pochi semplici step, anche senza grandi conoscenze nella programmazione. Prima di iniziare vorrei anche precisare che il sistema perfetto non esiste! Piuttosto, ogni configurazione evolve nel tempo per adattarsi ai propri bisogni.
Cos’è Obsidian
Obsidian non è altro che un systema per la gestione della conoscenza basato sula sintassi markdown e l’interconnessione delle differenti note. Ho già parlato di Obsidian e del perchè lo utilizzo quotidianamente in un articolo precedente:
In modo meno complesso, non è altro che un software che permette di scrivere e leggere dei file di testo che possono connessi tramite dei [[link]]
, vengono inserite tramite la doppia parentesi quadra e sono bidirezionali tra i due file.
Informazioni tecniche
La sintassi markdown è solo la punta dell’icesberg. Infatti, il sistema può essere migliorato di molto avvalendosi dei plugin, sia proprietari di Obsidian che dell’intera community. Io attualmente ne utilizzo diversi, quali:
- Autocomplete
- Calendar
- Dataview
- Mind Map
- Charts
- Quick Latex
- Reminder
- Table of Contents
- Tasks
- Templater
- Zoottelkeeper
Molti di questi verranno descritti più avanti, a partire dalle loro funzionalità.
Multi piattaforma
Obsidian può essere utilizzato su diversi dispositivi e sistemi operativi, sincronizzato le diverse note. Tuttavia, la realizzazione pratica può dare alcuni problemi.
Inizialmente ho provato la sincronizzazione con GitHub, tramite un repository privata, ma risultava piuttosto lenta e doveva essere richiesta manualmente. Esiste la possibilità di abilitare il push automatico ma spesso porta ad un freeze dell’app. Inoltre, questo metodo non permette la sincronizzazione su iOS.

Successivamente, sono passato alla sincronizzazione con iCloudDrive che in teoria dovrebbe funzionare sia su Apple (laptop e mobile) che su Windows. Tuttavia, con un utilizzo intenso porta ad alcuni problemi, tra cui la duplicazione delle note e la perdita di alcuni cambiamenti. Ovviamente, è anche possibile utilizzare qualsiasi servizio di clouding ma si perde la sincronizzazione nell’app mobile.
Alla fine mi sono convinto a passare ad Obsidian sync. Questo ha cambiato tutto! Adesso posso sincronizzare non solo tutte le note, ma anche le impostazioni, i plugin, impostazioni estetiche e tutti i diversi file presenti. Ha un costo di 10$ al mese ma può essere ridotto con il pagamento annuale o con sconti per studenti. Chiaramente, prevedo anche dei backup in quanto tutte le cartelle principali sono salvate all’interno sia di iCloudDrive che OneDrive.
Cartelle
Utilizzo una struttura definita di cartelle principali che mi permettono di dividere diversi argomenti ed accedere facilmente alle varie note.
flowchart id.1(((myvault))) id.1-->id.2[(Daily Notes)]-.->id15(YYYY)-.->id16(MMM)-.->id17(dd) id.1-->id3(Writing)-.->id.4(My website) id3-.->id5(Other) id.1-->id6(Setting)-.->id18(Templates) id6-.->id19(Scripts) id.1-->id7(Project) id.1-->id8(People) id.1-->id9(University)-.->id20(Lectures) id9-.->id21(Topics) id.1-->id10(Resources)-.->id11(Literature) id10-.->id12(Books) id10-.->id13(Various) id.1-->id14(Workout) classDef default fill:#e8e8e8, stroke:#c2c0c0;
Il senso di questa suddivisione sarà man mano chiaro durante la descrizione dei diversi plugin. La più importante è sicuramente il percorso delle Daily Notes dove il singolo file giornaliero viene raccolto in una cartella identificata dal numero del giorno, a sua volta dentro la cartella del mese e dell’anno. Questo è molto utile per inserire, nella stessa cartella giornaliera, tutti i diversi input quali nuove note, immagini, pdf o parti di codice. Questo vale per tutti i file ad eccezione delle note al cui interno sono descritte persone, letteratura scientifica, libri o meeting, le quali hanno uno specifico template e uno script automatizzato che le sposta nel loro percorso predefinito.
Note giornaliere
Ogni giorno posso creare una nuova nota, sfruttato la funzionalità di Obsidian, e automaticamente avrà come titolo la data attuale. Inoltre, la stessa nota viene creata nell’aposita directory giornaliera. Ogni nota giornaliera è struttura secondo alcune sezioni principali:
- Tasks
- Meeting log
- Daily log
- Brainstorm
- Check list
L’intero processo è automatizzata. I riassunti dei meeting o degli allenamenti automaticamente mostrano i dati presenti nel database. Infatti, al passaggio del mouse è possibile anche vedere la finestra popup che mostra maggiore dettagli su quel collegamento. Questi database sfruttano dataview
, di cui parleremo più avanti.
Inoltre, manualmente inserisco alcune informazioni nella sezione di log. Tutte le parole di interesse possono essere collegate con le relative note. Inoltre, sfrutto le note giornaliere anche per tenere alcuni promemoria e scadenze importanti che devo ricordare.

Tasks
Una delle sezioni giornaliere di maggior importanza è quella dei task. Si basa su un plugin che permette di tracciare gli elementi di tipo checkbox
all’interno di tutte le directory. Ogni elemento con il tag #task
viene raccolto e mostrato all’interno delle note giornaliere. Chiaramente il tutto può essere arricchito con maggiori tag, date e opzioni di ricorrenza. Tutto può essere richiamato semplicemente attraverso un blocco tipo codice con la seguente query:
```tasks
```
Inoltre, è possibile suddividere i task in diversi argomenti. Ad esempio, utilizzo task per l’intero quarter, con il tag #Q
, altri per le scadenze degli esami (#sched
), della tesi (#🎓
) o per il mio sito web (#📠
). Il tutto viene rappresentato in una comoda interfaccia grafica che permette di spuntare i task completati, oppure di editare manualmente le varie informazioni accessorie.
```tasks
not done
path includes Thesis
description includes #🎓
```
Task da completare per il mio progetto di tesi
```tasks
not done
due before YYYY-MM-DD
description does not include #🎓
description does not include #sched
```
Task che devo completare entro oggi, ad eccezione di quelli per la tesi o gli esami
```tasks
done on YYYY-MM-DD
```
Task completati oggi
Chiaramente, all’interno delle note giornaliere le query per le date sono completate automaticamente a partire dai diversi template.
Templater
Uno dei plugin più interessanti è Templater. Tale plugin permette di creare delle note con una struttura definita andando a definire automaticamente alcuni campi. Risulta molto utile quando si desidera avere dei template predefiniti per note di diverso tipo. Io utilizzo diversi template e i più importanti riguardano note che descrivono persone, meeting, note giornaliere, libri e articoli scientifici.
All’interno di ogni template sono inclusi i tag per dataview
di cui parleremo meglio più avanti. Il grande vantaggio di Templater è però quello di poter creare variabili e funzioni all’interno delle note. Inoltre, queste variabili possono essere manipolate, anche eseguendo codice in JavaScript. Ad esempio, dalla documentazione del plugin possiamo estrarre questo breve esempio:
---
creation date: <% tp.file.creation_date() %>
modification date: <% tp.file.last_modified_date("dddd Do MMMM YYYY HH:mm:ss") %>
---
<< [[<% tp.date.now("YYYY-MM-DD", -1) %>]] | [[<% tp.date.now("YYYY-MM-DD", 1) %>]] >>
# <% tp.file.title %>
<% tp.web.daily_quote() %>
E, una volta completato, ci resitutisce:
---
creation date: 2022-10-31 17:20
modification date: Wednesday 31th October 2022 17:20:43
---
<< [[2022-10-30]] | [[2022-11-01]] >>
# Test Test
> Do the best you can until you know better. Then when you know better, do better.
> <cite>Maya Angelou</cite>
Da questo semplice esempio possiamo arrivare a qualcosa di più complesso come il seguente, estratto dal mio template delle note per descrivere persone. Posso registrare diverse informazioni quali l’azienda, email, città e altre informazioni. Inoltre, viene richiamato dataview
anche per inserire una tabella riepilogativa dei meeting avuti con tale persona.
---
company::
location::
title::
email::
aliases::
languages::
date_last_spoken::
---
# [[<% tp.file.title %>]]
<% await tp.file.move("/People/"+tp.file.title)%>
## Meetings
```dataview
TABLE file.name as "Name",
date as "Date",
summary as "Summary"
from [[<% tp.file.title %>]]
where contains(type,"meeting")
sort date asc
```
Quindi riesco a creare la nota veramente facilmente, includendo automaticamente le informazioni su tutti i meeting in comune e lasciando la ripetizione del template al plugin.
Quando inizializzo la nuova nota, con una semplice combinazioni di tasi, inserirsco il template desiderato e completo i campi. In questo modo riesco ad avere le note automaticamente interconnesse, piene di informazioni utile e l’intero ‘database’ è molto versatile. In caso di necessità, posso cambiare le tabelle riepilogative semplicemente cambiando qualche query.

Database all’interno Obsidian
La tabella dei meeting precedentemente citata è realizzata grazie al plugin dataview. È un motore di indicizzazione e ricerca in tempo reale che realmente può trasformare il proprio Obsidian. Il suo funzionamento è diviso in due parti centrali: i dati e le query. I vari dati possono essere inseriti all’interno del file markdown direttamente seguendo la sintassi YAML:
---
field1::value1
field2::value2
---
Tramite le query è possibile richiamare e filtrari i dati. È possibile utilizzare sia il liguaggio DQL
(Dataview Query Language, una versione proprietaria derivata dal SQL) sia ataviewJS
(basato su API JavaScript).
Meeting log
Queste funzionalità mi permettono di creare mini strutture molto simili a databse. Ad esempio, andando a vedere lo script precedente all’interno delle note per descrivere le persone, nella tabella i dati vengono letti da type::#meeting
. Questo è automaticamente collegato a tutte le note dei meeting che nell’intestazione contengono:
---
type:: meeting
tag:: #meeting
company:: [[ ]]
summary::
date:: [[<%tp.date.now("YYYY-MM-DD")%>]]
---
Quindi, tale query restituisce una tabella con tutti i meeting che ho avuto in comune con quella persona. Tale tabella è dinamica e viene continuamente aggiornata da Obsidian.
Grafici
Utilizzo funzionalità simile anche per creare dei grafici per i miei dati di allenamento. Salvo ogni allenamento con le informazioni sui singoli esercizi attraverso un codice scritto da me di cui parlerò in un futuro articolo. All’interno di Obsidian ho tutte le informazioni su ripetizioni, serie e peso e posso richiamarle all’interno dei grafici con il seguente codice:
```dataview
TABLE WITHOUT ID
exerciseName as "Name",
SxR as "SxR",
max as "Max",
mean as "Mean",
std as "Std"
FROM "Workout"
WHERE contains(type,"gymExercise") and contains(string(date),"YYYY-MM-DD")
```
SxR | Max | Mean | Std | |
---|---|---|---|---|
Military press | 5x5 | 45 | 44 | 2 |
Lateral raises | 4x8 | 12 | 12 | 0 |
Front raises | 3x10 | 10 | 10 | 0 |
Dip | 4x8 | bw | bw | 0 |
Chin up | 4x8 | 0 | 0 | 0 |
Push down | 3x12 | 25 | 25 | 0 |
Push up | ced | bw | 0 | 0 |
Allo stesso modo posso utilizzare questi dati per creare dei grafici. Tale codice utilizza sia JavaScript
and dataview
, uniti con chart.js
che mi permette di renderizzare il grafico. Non è altro che una libreria opesource per visualizzare i dati. Permette infatti di creare diversi grafici quali linea, barre, torta, bolle o scatter.
let EX="Squat";
dv.header(3,EX);const maxvalue=dv.array(dv.pages('"Workout"').where(p=>p.exercisename && p.exerciseName.path==EX && p.dateNoLink<dv.date("YYYY-MM-DD")+1 ).max );
const meanvalue=dv.array(dv.pages('"Workout"').where(p=>p.exercisename && p.exerciseName.path==EX && p.dateNoLink<dv.date("YYYY-MM-DD")+1).mean );
const mylabel=dv.array(dv.pages('"Workout"').where(p=>p.exercisename && p.exerciseName.path==EX && p.dateNoLink<dv.date("YYYY-MM-DD")+1).dateNoLink);
const chartData = {
type: 'line',
data: {
labels: mylabel.map(t => t.toLocaleString([], { month: '2-digit', day: '2-digit', year: '4-digit', hour: '2-digit', minute: '2-digit' })),
datasets: [{
label: "Max",
data: maxvalue.values,
backgroundColor: ['#ba342b'],
borderWidth: 1
},{
label: "Mean",
data: meanvalue.values,
backgroundColor: ['#a0ada3'],
borderWidth: 1
}]
}
}
window.renderChart(chartData, this.container);
Birre artigianali
Ma c’è anche qualcosa di più divertente. Utilizzo questi plugin anche per creare un interessante database di tutte le birre bevute. Si basa su una singola nota per ogni birra, con uno specifico template.
---
type:: beer
style:: [[beer style]]
manufacturer:: [[Manufacturer]]
country::
drunk::
---
# [[<% tp.file.title %>]]
**Style**: [[beer style]]
**Colour**:
**Aroma**:
**Taste**:
**Bitter**:
**Alcohol**:
**Country**:
**Manufacturer**: [[ ]]
Il template mi permette di raccogliere diverse informazioni che quindi posso richiamare all’interno di una tabella prinicipale. In questa tabella posso filtrare le birre per origine, stile, azienda, ecc. Per ogni elemento descrivi anche il tipo di birra, l’aroma e il gusto, collegando tra loro le diverse note.

Questi esempi voglioni mostrare come non c’è limite a ciò che si può creare.
Inoltre, utilizzo anche un template per gli articoli scientifici o per i libri che leggo. In ogni nota posso inserire diverse informazioni e quindi richiamarle quando serve. Ad esempio, posso connettere tutte le informazioni attraverso una tabella (o una lista) di riepilogo.
Mermaid
Infine, l’ultimo plugin di cui voglio parlare è mermaidjs
. Basato su JavaScript, è un potente tool per fare diagrammi e grafici che possono essere modificati dinamicamente. Nonostante la definizione, vediamo con alcuni esempi come può risultare utile.
```mermaid
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B ---->|No| E[End]
```
flowchart TD A[Start] --> B{Is it?} B -->|Yes| C[OK] C --> D[Rethink] D --> B B ---->|No| E[End]
Permette di scrivere molto velocemente dei diagrammi di flusso semplicemente indirizizzando un blocco al successivo: block1-->block2
. Inoltre, si possono creare anche altri diagrammi come sequenze, diagrammi di classi e grafici stile git.
sequenceDiagram
Federica->>Luigi: Hello Luigi, how are you?
Luigi-->>Federica: Great!
Federica-)Giacomo: See you later!
sequenceDiagram Federica->>Luigi: Hello Luigi, how are you? Luigi-->>Federica: Great! Federica-)Luigi: See you later!
classDiagram direction RL class Student { -idCard : IdCard } class IdCard{ -id : int -name : string } class Bike{ -id : int -name : string } Student "1" --o "1" IdCard : carries Student "1" --o "1" Bike : rides
classDiagram
direction RL
class Student {
-idCard : IdCard
}
class IdCard{
-id : int
-name : string
}
class Bike{
-id : int
-name : string
}
Student "1" --o "1" IdCard : carries
Student "1" --o "1" Bike : rides
gitGraph
commit id:"A"
commit id:"B"
branch mybranch
commit id:"C"
commit id:"D"
commit id:"E"
checkout main
commit id:"F"
commit id:"G"
gitGraph commit id:"A" commit id:"B" branch mybranch commit id:"C" commit id:"D" commit id:"E" checkout main commit id:"F" commit id:"G"
Theme and graphic design
Anche l’occhio vuole la sua parte! All’interno di Obsidian è possibile personalizzare l’interfaccia grafica. Io attualmente utilizzo il tema Pine Forest Berry, leggermente diverso da quello di default. Presenta un’interessante palette cromatica con un design minimalista. Utilizzo la modalità chiara che secondo me risulta molto più leggibile e meno stancante per gli occhi.

Ma all’interno di Obsidian è possibile personalizzare completamente l’interfaccia grafica agendo direttamente sul proprio CSS. Tramite la scorciatoia ctrl+shitft+i
si può inspezionare il documento andando a vedere stili e classe desiderate. Ad esempio, io ho personalizzato alcune impostazioni per la finestra popup, i grafici mermaid e il colore di alcuni stili tipografici.
.theme-light{
--text-highlight-bg: rgba(161, 161, 131, 0.3);
--popover-font-size: 11px;
--blockquote-background-color: rgba(172, 172, 172, 0.105);
}
.popover{
--text-title-h1: #b48196;
--link-color: #c19760 ;
--blockquote-background-color: rgba(113, 113, 113, 0.519);
font-size: 11px !Important;
}
.popover.hover-popover {
position: absolute;
transform: scale(0.9); /* makes the content smaller */
max-height: 700px; /* was 300 */
width: 800px; /* was 400 */
overflow: overlay;
}
.popover.hover-popover.is-loaded { /* nice shadow */
border: 1px solid darkgrey;
box-shadow: 6px 6px 7px #50535c72;
border-radius: 6px;
}
strong, .cm-strong {
font-weight: 600;
color: rgb(123, 60, 142);
}
.mermaid {
max-width: 80%;
overflow: scroll;
}
.mermaid svg {
min-height:20px;
width: auto;
}
.markdown-preview-view table {
display: block;
max-width: -moz-fit-content;
max-width: fit-content;
margin: 0 auto;
overflow-x: scroll;
white-space: nowrap;
}