in Dagelijks

jrnl: hoe ik per ongeluk een CMS bouwde

Aan het begin van dit jaar schreef ik over hoe ik journal. Ik ging toen van papier naar digitaal.

TLDR: in mijn journal staan dingen voor mij, op mijn blog deel ik dingen met jou.

En dat werkte best goed. Het was dan ook re-de-lijk simpel opgezet.

Maar één paar dingetjes stonden me tegen.

  • Als ik iets wou aanpassen dan was dat lastig. Het Journal was bijna als Twitter: niet aan te passen. Ok, ok, het kon wel maar dat was gedoe en brak de flow (het aanpassen moest op een andere plek dan het aanmaken etc.)
  • De hele opzet kon volgens mij toch nóg simpeler.

En na bijna 11 maanden dit dagelijks op deze manier te hebben gebruikt, wist ik ook beter wat ik wel en niet wou. En wat ik vooral wou is dit:

  • Een website waar ik de hele dag door makkelijk dingen kan aanpassen en toevoegen.
  • Iets dat nog platter en simpeler is. De eerste oplossing bestond uit 4 verschillende dingen: Google Form, Google Sheet, shell cron, en een stukje PHP code.

Dus in een klassiek gevalletje van yak-shaving — met een beetje van ChatGPT en een beetje van Jan — heb ik een paar weken geleden een nieuwe dagboek tool gemaakt: jrnl.

De afkorting is een backroniem voor Jan’s Reflective Notes Log.

Tech stack

Het is zo eenvoudig mogelijk als het maar kan, twee PHP scripts en een SQLite database:

  • index.php – geeft een overzicht van alle dagen, de nieuwste bovenaan
  • entry.php – voor toevoegen of bewerken van een dag
  • journal.db – een SQLite database waar alles in staat

En dat is het. Dus een viewer (index.php), tekstverwerker (entry.php) en de data (journal.db).

index.php

Als ik een nieuwe dag wil toevoegen klik ik op jrnl. Wil ik een dag bewerken dan klik ik op de datum van die dag.

Het bewerkveld ziet er zo uit.

entry.php

En dit is de database structuur:

-- journal.sql
CREATE TABLE IF NOT EXISTS journal_entries (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    date DATE NOT NULL,
    location TEXT CHECK (location IN ('Home', 'Office')),
    reflections TEXT,
    smiley INTEGER CHECK (smiley IN (1, 2))
);

Het kan bijna niet simpeler.

En toen ik dit had gebouwd dacht ik: oh, maar wacht eens even, ik heb nu eigenlijk een CMS gebouwd.

Een CMS in de meest pure vorm.

Want jrnl is een chronologisch overzicht van posts, waar de nieuwste altijd bovenaan staan en die ik kan bewerken. Ja, dit is een blog CMS.

Oh well.

SQLite ❤

Dit was mijn eerste SQLite projectje, ik doe normaal alles met MySQL/MariaDB, want dat ken ik goed, maar ik wou het zo simpel en portable mogelijk houden. Dat is SQLite. Doodsimpel en snel. Nog sneller dan ik dacht. Dat ga ik vaker gebruiken.

Daarnaast heb ik alles wat in oude bestand stond, gemigreerd naar deze SQLite database. Zo dat heel 2024 ook in jrnl staat. Daar ben ik mogelijk nog langer mee bezig geweest dan het maken van jrnl zelf. Lang verhaal kort: ik heb alles gedumpt naar een CSV bestand. En dat bestand weer geïmporteerd in de SQLite database met een stukje Python code. Dat was even passen meten maar dat werkte uiteindelijk perfect.

import sqlite3
import csv

# Connect to SQLite database
conn = sqlite3.connect('journal.db')
cursor = conn.cursor()

# Open the CSV file
with open('jrnl.csv', 'r', newline='', encoding='utf-8') as csvfile:
    csvreader = csv.reader(csvfile)
    
    # Skip the header row if present
    # next(csvreader)

    # Insert each row, mapping columns to the correct order
    for row in csvreader:
        # Adjust the indices in row[] to match the CSV column order
        location = row[2]    # Assuming 'location' is first in CSV
        reflections = row[1]  # 'reflections' is second in CSV
        smiley = row[3]      # 'smiley' is third in CSV
        date = row[0]        # 'date' is last in CSV
       
        #print(reflections)
        #cursor.execute('''
        #print("INSERT INTO jrnl_entries (date, location, reflections, smiley) VALUES (",date, reflections, location, smiley")")
        #''', (date, location, reflections, smiley))

        cursor.execute('''
            INSERT INTO jrnl_entries (date, location, reflections, smiley) 
            VALUES (?, ?, ?, ?)
        ''', (date, location, reflections, smiley))

# Commit changes and close connection
conn.commit()
conn.close()

Ook hier is weer de kracht A.I. te merken, want ook dat stukje Python had ik zelf wel kunnen maken maar nu was het in een paar tellen klaar. Alleen het testen en her-aanpassen duurde wat langer ivm hoe ik de CSV had op gemaakt.

jrnl

Ik kan er enorm van genieten dat jrnl een compleet portable en doodeenvoudige oplossing is die precies doet wat ik wil. Door middel van drie bestandjes kan ik nu de hele dag door mijn leven vastleggen. Het zijn drie bestandjes die ik naar bijna elke webserver kan verplaatsen en dan werkt het ook.

Met een beetje moeite denk ik dat het trouwens zelfs in 2 bestanden kan: 1 PHP bestand en 1 database. 🙈

Ik typ de hele dag door in jrnl, het is bijna mijn tweede brein geworden. Wat ik doe, werk ik thuis of op kantoor (handig voor declaraties), waarom ik iets doe, met wie heb ik gesproken, wat ik van de boekenclubavond vond, hoe de vergadering van de stichting of commissie ging, hup allemaal even in het journal. Dingen die ik kwijt wil. En het is bloedje-snel, ik hoef dus ook geen zoekfunctie in te bouwen; gewoon ctrl-f op de site.

Ik kan genieten van dit soort simpele dingen die het leven wat makkelijker maken. Ik zou de code kunnen delen, maar het is zo triviaal, met een paar vragen aan ChatGPT kun jij hetzelfde maken!

Laat een reactie achter

Reactie