Ciao! Se è la prima volta che capiti su questo sito, ti consiglio di consultare la pagina principale di questo cosiddetto Giardino Digitale per scoprire meglio cos’è e come navigarlo.
Lo stato di questa nota è al momento: 🟢 Completa.
Stai creando un tuo Giardino Digitale in cui vuoi inserire una funzionalità presente nel mio? Sei nel posto giusto!
Man mano che modifico le impostazioni di questo Giardino Digitale discostandomi dal template di default, segno qua tutto ciò che faccio, anche con l’obiettivo di facilitare il lavoro al me del futuro nel caso in cui ci sia bisogno di ricreare da zero il repository.
Nel caso in cui non ti fosse chiaro quello che spiego qua in questa nota, puoi direttamente consultare il codice sorgente del sito andando sul repository.
1 - Punto di partenza
Come punto di partenza c’è, ovviamente, la creazione del giardino digitale a partire dal template di default che Quartz offre.
Le istruzioni su come costruire e impostare inizialmente un giardino digitale si trovano nella home page di Quartz.
Qua sotto riporto un paio di problemini che ho riscontrato durante l’installazione di Quartz:
Attenzione: errore nel cloning del repository
Se durante il cloning del repository (cioè dopo aver eseguito il comando git clone https://github.com/jackyzha0/quartz.git) esce il seguente messaggio
error: RPC failed; curl 92 HTTP/2 stream 5 was not closed cleanly: CANCEL (err 8)error: 40 bytes of body are still expectedfetch-pack: unexpected disconnect while reading sideband packetfatal: early EOFfatal: fetch-pack: invalid index-pack output
basta rieseguire di nuovo questo comando, perché significa che c’è stato un errore di connessione durante l’operazione.
Attenzione: errore nell'esecuzione di npm i
Se durante l’installazione di Quartz, dopo aver eseguito il comando npm i, esce un errore del tipo
added 526 packages, and audited 528 packages in 9s173 packages are looking for funding run npm fund for details3 vulnerabilities (2 moderate, 1 high)To address all issues, run: npm audit fixRun npm audit for details.
allora eseguire il comando npm audit fix per risolvere.
2 - Configurazione
Ecco quindi tutte le modifiche che ho applicato al sito per personalizzarlo.
2.1 - Configurazione generale
Nel file quartz.config.ts ho configurato queste impostazioni generali:
pageTitle: "🪴 Giardino Digitale di Rexus752": titolo del Giardino Digitale che compare sulla sinistra di ogni nota.
locale: "it-IT": per impostare la lingua in italiano.
baseUrl: "rexus752.github.io/digital-garden": URL del sito (anche se in realtà nella mia configurazione non serve a qualcosa in particolare).
ignorePatterns: []: in questo modo salva nel repository ogni cartella, anche quelle nascoste di default come la .obsidian contenente le impostazioni del vault di Obsidian ed eventuali cartelle private contenenti note private (che però io non uso) e templates contenenti template per le note.
Per il body, cioè il testo normale come questo che stai leggendo, uso il typeface Inter, ossia lo stesso che GNOME usa di default a partire dalla versione 47 e che io reputo uno dei migliori sulla piazza al momento (è anche completamente gratuito!).
Per il codice, uso il typeface Fira Code, studiato appositamente per creare legature, cioè unioni tra due o più glifi (simboli, lettere, ecc.). Per esempio, se scrivo due volte di fila =, Fira Code mi mostra un unico segno: ==.
Per usare questi font, ho modificato il file quartz.config.ts in questo modo:
Il mio Giardino Digitale contiene note divise per cartelle a seconda dell’argomento di cui trattano. Ogni cartella ha una nota associata e le relative sotto-cartelle e sotto-note comprese in quell’argomento.
Per esempio, la cartella Matematica contiene la nota Matematica.md che fa da introduzione a quell’argomento e le sue sotto-cartelle come Teoria degli insiemi che a sua volta avrà la sua nota principale:
📂 Matematica/
├── 🗒 Matematica.md
├── 🗒 Analisi.md
└── 📂 Teoria degli insiemi/
└── 🗒 Teoria degli insiemi.md
Problemino: Quartz genera delle pagine web non solo per le note, ma anche per le cartelle stesse (nella pagina della cartella ti inserisce i link alle note contenute nella cartella). Ciò significa che, per esempio, la nota Matematica.md è disponibile al percorso ./Matematica/Matematica.md, perché al percorso ./Matematica apre la pagina della cartella Matematica.
Per ovviare a questo problema, Quartz offre già a priori una soluzione: nella cartella desiderata, si può rinominare la sua “nota associata” in _index.md o index.md in modo da sostituirla alla nota della cartella. Il titolo della nota lo prende dalla proprietà title inserita nel frontmatter della nota.
Attenzione: _index.md o index.md?
Riguardo quest’ultima cosa, sono stato costretto a scegliere _index.md come nome di default per le note associate alle cartelle, perché index.md l’ho riservato alla nota della homepage del sito (cioè content/index.md). Ho dovuto fare così perché, in questo modo, nelle premesse delle note posso mettere un link che reindirizza semplicemente all’unica nota che in tutto il vault di Obsidian ha come nome index.md, ossia proprio content/index.md. Se anche questa nota avesse come nome _index.md, Obsidian “forza” a inserire come percorso nell’hyperlink il percorso content/_index.md, generando il problema per cui, sul sito, questo hyperlink rimanda alla nota https://rexus752.github.io/digital-garden/content/_index.md che non esiste.
Quindi, nella cartella Matematica, la nota Matematica.md diventa _index.md e, quando nell’Esplora sul lato della pagina cliccherò su Matematica, non mi porterà alla pagina della cartella, ma a quella della nota Matematica.md.
Il risultato è il seguente:
📂 Matematica/
├── 🗒 _index.md
├── 🗒 Analisi.md
└── 📂 Teoria degli insiemi/
└── 🗒 _index.md
Per evitare che comunque le pagine associate delle cartelle mostrino sotto il contenuto della nota associata anche il contenuto della cartella, ho modificato il file quartz/components/pages/FolderContent.tsx commentando queste righe di codice:
Ho aggiunto anche in defaultListPageLayout le componenti incluse nel right di defaultContentPageLayout perché, dato il particolare file system che uso in questo Giardino Digitale, tutte le note associate alle cartelle (ossia quelle che si chiamano _index.md) prendono il layout da defaultListPageLayout e, di default, non avrebbero queste componenti:
quartz.layout.ts
Nel layout delle pagine ho anche rimosso i grafici, sia in defaultContentPageLayout che in defaultListPageLayout, che per quanto possano essere carini sono comunque inutili:
quartz.layout.ts
Nella cartella quartz/static ho sostituito il file icon.png con una mia icona personalizzata, che è appunto l’icona di questo Giardino Digitale:
Questa l’ho creata attraverso il generatore sul sito ufficiale di Obsidian che ti permette di personalizzare la nuova icona di Obsidian adottata nel 2023 con i tuoi colori. Io ho usato gli stessi colori della mia classica immagine di profilo che uso ovunque, ossia quella di Patrick con il cervello esploso:
Ne ho approfittato anche per sostituire con questa icona il file og-image.png, sempre nella cartella quartz/static, che è la foto che compare nelle preview del Giardino Digitale quando si inserisce il link in un messaggio:
Facendo ciò ho anche disabilitato il plugin Custom OG Images nel file quartz.config.ts, che è il plugin che si occupa di generare delle preview uniche per ogni nota del sito (e che, come specifica il commento nel codice, rallenta il tempo di build del sito):
quartz.config.ts
const config: QuartzConfig = { plugins: { emitters: [ Plugin.AliasRedirects(), Plugin.ComponentResources(), Plugin.ContentPage(), Plugin.FolderPage(), Plugin.TagPage(), Plugin.ContentIndex({ enableSiteMap: true, enableRSS: true, }), Plugin.Assets(), Plugin.Static(), Plugin.Favicon(), Plugin.NotFoundPage(), // Comment out CustomOgImages to speed up build time // Plugin.CustomOgImages(), ], },}
2.6 - Modalità scura di default
Nel mio Giardino Digitale, per questione di comodità, ho scelto di inserire la modalità scura di default e tolto la possibilità di passare alla modalità chiara. Ciò l’ho fatto perché io in primis, quando scrivo le mie note su Obsidian, uso la modalità scura, e di conseguenza anche tutti i contenuti che ho inserito nelle note come le foto o gli schemi sono adattati a questo tema. Mantenere la possibilità di passare alla modalità chiara significherebbe dover creare un sistema per cui anche queste foto debbano adattarsi alla modalità chiara, cosa che non ho assolutamente intenzione di fare lol.
Impostare la modalità scura di default sul sito è un bel casino, ci ho messo un bel po’ per capire come straminghie farlo, ma alla fine ho scelto l’opzione più stupida e più diretta per realizzarlo: nel file quartz.config.ts ho scambiato di posto le parole lightMode e darkMode:
Per applicare la modalità scura fissa anche nel syntax highlighting (cioè il colore nel codice) ho modificato le impostazioni del relativo plugin che si possono trovare in quartz.config.ts, semplicemente scambiando i valori github-light e github-dark:
Per invertire i colori anche nei diagrammi, non so come si possa fare ora nelle ultime versioni di Quartz (e per questo proverò ad astenermi dall’usare i diagrammi Mermaid nel sito, altrimenti sembrano uno schifo i diagrammi in modalità chiara con il resto del sito in modalità scura). Se può essere utile saperlo per trovare magari una soluzione, posso dirti che nella versione 4.4 di Quartz, nel file quartz/plugins/transformers/ofm.ts, approssimativamente alla riga 695, bisognava scambiare i valori 'dark' e 'default':
Infine, ho rimosso il pulsante per passare dalla modalità chiara a quella scura e viceversa in quartz.layout.ts, sia in defaultContentPageLayout che in defaultListPageLayout:
Esattamente come avrai potuto notare con quelle che ho inserito qua sopra, le foto vengono automaticamente centrate nel mezzo della pagina.
Ciò si può fare modificando il codice SCSS del sito, infatti Quartz mette a disposizione il file custom.scss nella cartella quartz/styles per scriverci le proprie modifiche.
In nome del sacro principio della modularità del codice, ho inserito questa modifica in un file centered-photos.scss in una sotto-cartella custom della cartella quartz/styles che, appunto, conterrà tutte le varie modifiche da applicare all’SCSS del sito.
Quindi, nel file centered-photos.scss in quartz/styles/custom ci ho scritto questo:
quartz/styles/custom/centered-photos.scss
img { display: block; margin: auto;}
E, per dire a Quartz di leggere questo file, nel file custom.scss nella cartella quartz/styles ci ho scritto ciò:
All’interno del mio Giardino Digitale, uso diversi callout personalizzati, descritti attraverso codice SCSS. Tutti i callout che ho aggiunto sono inseriti nel file callouts.scss nella cartella quartz/styles/custom col seguente formato:
Lo aggiungo nel file callouts.scss sostituendo la stringa <URL-encoded SVG> con quella appena copiata.
Qua sotto ho inserito una lista dei callout che uso, ognuno dei quali ha al proprio interno il codice SCSS per impostarlo (clicca sulla freccetta affianco al titolo del callout per espanderlo).
In questo Giardino Digitale, ogni nota ha associata una icona colorata in formato SVG. Le icone le prendo da FontAwesome e da Tabler Icons e le inserisco nella cartella content/_icons con lo stesso nome della nota a cui fa riferimento.
Per modificare il colore delle icone scaricate, prima le formatto usando lo script svg-formatter.py che ho scritto io con le mie manine (e che si trova ovviamente nella cartella content/scripts) e poi modifico a mano il codice SVG impostando il colore desiderato nel parametro fill.
Per aggiungere le icone affianco ai titoli delle note, ho modificato il file quartz/components/ArticleTitle.tsx in questo modo:
Piccolo disclaimer: lo so che questa porzione di codice l’ho scritta col culo, ma non sono un web developer e a malapena so destreggiarmi con il TypeScript. Ci sono sicuramente modi più puliti per realizzare quello che voglio fare, ma ci accontentiamo.
Per aggiungere le icone ai titoli delle note anche all’interno dell’Esplora sul lato della pagina, ho chiesto sul server Discord ufficiale di Quartz un aiutino su come farlo ma nessuno mi ha aiutato. Allora ho chiesto un aiutino al mio caro amico Deepseek, che in un quarto d’ora ha saputo aiutarmi a raggiungere il risultato voluto.
Specifico che ogni componente è duplicato solo perché, hostando il sito sulle GitHub Pages, i percorsi relativi partono dal dominio del sito (cioè rexus752.github.io) e non dalla “pagina” del Giardino Digitale (cioè rexus752.github.io/digital-garden), ossia da quello che effettivamente dovrebbe essere l’equivalente della cartella content del vault di Obsidian. Ciò implica che, buildando il sito in locale, le icone delle note si trovano nella cartella /_icons/, mentre buildando il sito online le icone si trovano nella cartella /digital-notes/_icons/. Non ho trovato un modo per rendere questi percorsi relativi “dinamici” a seconda della situazione (build in locale od online) e, come soluzione più facile, ho deciso di inserire per ogni icona una coppia di elementi: uno che cerca l’icona al percorso /_icons/, l’altro al percorso /digital-notes/_icons/. Funziona perché a prescindere uno dei due troverà l’icona al percorso desiderato e l’altro no, quindi comparirà sempre una sola icona.
Quello che ho fatto è stato:
Aggiungere nel file quartz/components/scripts/explorer.inline.ts sia nella funzione createFileNode che nella funzione createFolderNode questi pezzi di codice che integrano le icone nei template che Quartz usa per generare le entry dei file e delle cartelle nell’Explorer:
quartz/components/scripts/explorer.inline.ts
function createFileNode(currentSlug: FullSlug, node: FileTrieNode): HTMLLIElement { const template = document.getElementById("template-file") as HTMLTemplateElement const clone = template.content.cloneNode(true) as DocumentFragment const li = clone.querySelector("li") as HTMLLIElement const icon_local = li.querySelector(".file-icon-local") as HTMLImageElement if (icon_local) { icon_local.src = `/_icons/${node.displayName.replaceAll(" ", "-")}.svg` icon_local.alt = "" } const icon_sync = li.querySelector(".file-icon-sync") as HTMLImageElement if (icon_sync) { icon_sync.src = `/digital-garden/_icons/${node.displayName.replaceAll(" ", "-")}.svg` icon_sync.alt = "" } const a = li.querySelector("a") as HTMLAnchorElement a.href = resolveRelative(currentSlug, node.slug) a.dataset.for = node.slug a.textContent = node.displayName if (currentSlug === node.slug) { a.classList.add("active") } return li}function createFolderNode( currentSlug: FullSlug, node: FileTrieNode, opts: ParsedOptions,): HTMLLIElement { const template = document.getElementById("template-folder") as HTMLTemplateElement const clone = template.content.cloneNode(true) as DocumentFragment const li = clone.querySelector("li") as HTMLLIElement const icon_local = li.querySelector(".folder-icon-local") as HTMLImageElement if (icon_local) { icon_local.src = `/_icons/${node.displayName.replaceAll(" ", "-")}.svg` icon_local.alt = "" } const icon_sync = li.querySelector(".folder-icon-sync") as HTMLImageElement if (icon_sync) { icon_sync.src = `/digital-garden/_icons/${node.displayName.replaceAll(" ", "-")}.svg` icon_sync.alt = "" } const folderContainer = li.querySelector(".folder-container") as HTMLElement const titleContainer = folderContainer.querySelector("div") as HTMLElement const folderOuter = li.querySelector(".folder-outer") as HTMLElement const ul = folderOuter.querySelector("ul") as HTMLUListElement // ...}
Aggiungere effettivamente nel template delle entry in quartz/components/Explorer.tsx i tag <img> per inserire le icone:
quartz/components/Explorer.tsx
Per evitare che l’icona faccia allineare il nome della cartella a destra, nel file quartz/components/styles/explorer.scss ho modificato il tipo di display:
quartz/components/styles/explorer.scss
Nel .gitignore ho rimosso le cartelle .obsidian e private così, in caso di eventi catastrofici, non perdo i loro contenuti e posso tranquillamente recuperarli dal repository del Giardino Digitale.
3 - Da fare
Questo è ciò che ho in mente di fare per migliorare il sito:
Ridurre lo spazio vuoto in cima alle pagine del sito.
Integrare le icone delle note anche nel Breadcrumbs.
Rinominare “Vista grafico” in qualcos’altro di più vicino all’italiano corretto.
Integrare Giscus.
Sostituire il codice CSS delle tabelle.
Trasformare la “Reader Mode” in una modalità dyslexic-friendly (es. usando il font OpenDyslexic).
Renderizzare il LaTeX nei titoli dell’indice sul lato delle pagine.