Implement dynamically getting board data

This commit is contained in:
Dominic Ferrando
2025-04-17 19:27:47 -04:00
parent 576cc763b0
commit e5b52712d1
16 changed files with 135 additions and 26 deletions
+1 -1
View File
@@ -1 +1 @@
internal/db/comfychan.db internal/database/comfychan.db
+2 -2
View File
@@ -14,8 +14,8 @@ live:
make -j2 live/templ live/sync_assets make -j2 live/templ live/sync_assets
db/seed: db/seed:
sqlite3 ./internal/db/comfychan.db < ./internal/db/seed.sql sqlite3 ./internal/database/comfychan.db < ./internal/database/seed.sql
db/seed/f: db/seed/f:
rm ./internal/db/comfychan.db && sqlite3 ./internal/db/comfychan.db < ./internal/db/seed.sql rm ./internal/database/comfychan.db && sqlite3 ./internal/database/comfychan.db < ./internal/database/seed.sql
+19 -4
View File
@@ -1,11 +1,13 @@
package main package main
import ( import (
"database/sql"
"fmt" "fmt"
"net/http" "github.com/dominicf2001/comfychan/internal/database"
"github.com/dominicf2001/comfychan/web/views" "github.com/dominicf2001/comfychan/web/views"
"github.com/dominicf2001/comfychan/web/views/boards" _ "github.com/mattn/go-sqlite3"
"log"
"net/http"
) )
var dev = true var dev = true
@@ -21,6 +23,12 @@ func disableCacheInDevMode(next http.Handler) http.Handler {
} }
func main() { func main() {
db, err := sql.Open("sqlite3", "internal/database/comfychan.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
http.Handle("/static/", http.Handle("/static/",
disableCacheInDevMode( disableCacheInDevMode(
http.StripPrefix("/static", http.StripPrefix("/static",
@@ -31,7 +39,14 @@ func main() {
}) })
http.HandleFunc("/comfy", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/comfy", func(w http.ResponseWriter, r *http.Request) {
boards.Comfy().Render(r.Context(), w) board, err := database.GetBoard(db, "comfy")
if err != nil {
http.Error(w, "Failed to load boards", http.StatusInternalServerError)
log.Printf("Error fetching boards: %v", err)
return
}
views.Board(board).Render(r.Context(), w)
}) })
fmt.Println("Listening on :8080") fmt.Println("Listening on :8080")
+2
View File
@@ -3,3 +3,5 @@ module github.com/dominicf2001/comfychan
go 1.23.8 go 1.23.8
require github.com/a-h/templ v0.3.857 require github.com/a-h/templ v0.3.857
require github.com/mattn/go-sqlite3 v1.14.28 // indirect
+2
View File
@@ -2,3 +2,5 @@ github.com/a-h/templ v0.3.857 h1:6EqcJuGZW4OL+2iZ3MD+NnIcG7nGkaQeF2Zq5kf9ZGg=
github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M= github.com/a-h/templ v0.3.857/go.mod h1:qhrhAkRFubE7khxLZHsBFHfX+gWwVNKbzKeF9GlPV4M=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
Binary file not shown.
+34
View File
@@ -0,0 +1,34 @@
package database
import (
"database/sql"
)
func GetBoards(db *sql.DB) ([]Board, error) {
rows, err := db.Query(`select id, name, slug, tag from boards order by slug`)
if err != nil {
return nil, err
}
defer rows.Close()
var result []Board
for rows.Next() {
var b Board
err := rows.Scan(&b.Id, &b.Name, &b.Slug, &b.Tag)
if err != nil {
return nil, err
}
result = append(result, b)
}
return result, rows.Err()
}
func GetBoard(db *sql.DB, slug string) (Board, error) {
row := db.QueryRow(`SELECT id, name, slug, tag FROM boards WHERE slug = ?`, slug)
var result Board
row.Scan(&result.Id, &result.Name, &result.Slug, &result.Tag)
return result, row.Err()
}
+26
View File
@@ -0,0 +1,26 @@
package database
import "time"
type Board struct {
Id int
Slug string
Name string
Tag string
}
type Thread struct {
Id int
BoardId int
Subject string
CreatedAt time.Time
BumpedAt time.Time
}
type Post struct {
Id int
ThreadId int
Author string
Body string
CreatedAt time.Time
}
@@ -8,13 +8,13 @@ CREATE TABLE IF NOT EXISTS boards (
id INTEGER PRIMARY KEY, id INTEGER PRIMARY KEY,
slug TEXT NOT NULL UNIQUE, slug TEXT NOT NULL UNIQUE,
name TEXT NOT NULL, name TEXT NOT NULL,
tag TEXT tag TEXT NOT NULL
); );
CREATE TABLE IF NOT EXISTS threads ( CREATE TABLE IF NOT EXISTS threads (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
board_id INTEGER NOT NULL, board_id INTEGER NOT NULL,
subject TEXT, subject TEXT NOT NULL DEFAULT '',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP, created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
bumped_at DATETIME DEFAULT CURRENT_TIMESTAMP, bumped_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE
-1
View File
@@ -1 +0,0 @@
package db
-1
View File
@@ -1 +0,0 @@
package internal
-1
View File
@@ -1 +0,0 @@
package internal
@@ -1,6 +1,10 @@
package boards package views
import "github.com/dominicf2001/comfychan/web/views/shared" import (
"fmt"
database "github.com/dominicf2001/comfychan/internal/database"
"github.com/dominicf2001/comfychan/web/views/shared"
)
templ NewThreadForm() { templ NewThreadForm() {
<form style="display: none;" id="newThreadForm" style="display: ;"> <form style="display: none;" id="newThreadForm" style="display: ;">
@@ -21,14 +25,14 @@ templ NewThreadForm() {
</form> </form>
} }
templ Comfy() { templ Board(board database.Board) {
@shared.Layout() { @shared.Layout() {
<header class="board-header"> <header class="board-header">
<img src="/static/img/banner-comfy.png"/> <img src="/static/img/banner-comfy.png"/>
<h1> <h1>
"/comfy/" - Comfy { fmt.Sprintf("/%s/ - %s", board.Slug, board.Name) }
</h1> </h1>
<p>Be comfy fren</p> <p>{ board.Tag }</p>
</header> </header>
<div class="new-thread-container"> <div class="new-thread-container">
<button _="on click hide me then show #newThreadForm" id="newThreadBtn">[New Thread]</button> <button _="on click hide me then show #newThreadForm" id="newThreadBtn">[New Thread]</button>
@@ -1,14 +1,18 @@
// Code generated by templ - DO NOT EDIT. // Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.857 // templ: version: v0.3.857
package boards package views
//lint:file-ignore SA4006 This context is only used if a nested component is present. //lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ" import "github.com/a-h/templ"
import templruntime "github.com/a-h/templ/runtime" import templruntime "github.com/a-h/templ/runtime"
import "github.com/dominicf2001/comfychan/web/views/shared" import (
"fmt"
database "github.com/dominicf2001/comfychan/internal/database"
"github.com/dominicf2001/comfychan/web/views/shared"
)
func NewThreadForm() templ.Component { func NewThreadForm() templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
@@ -39,7 +43,7 @@ func NewThreadForm() templ.Component {
}) })
} }
func Comfy() templ.Component { func Board(board database.Board) templ.Component {
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
@@ -72,7 +76,33 @@ func Comfy() templ.Component {
}() }()
} }
ctx = templ.InitializeContext(ctx) ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<header class=\"board-header\"><img src=\"/static/img/banner-comfy.png\"><h1>\"/comfy/\" - Comfy</h1><p>Be comfy fren</p></header><div class=\"new-thread-container\"><button _=\"on click hide me then show #newThreadForm\" id=\"newThreadBtn\">[New Thread]</button>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<header class=\"board-header\"><img src=\"/static/img/banner-comfy.png\"><h1>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("/%s/ - %s", board.Slug, board.Name))
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/views/board.templ`, Line: 33, Col: 54}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</h1><p>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(board.Tag)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/views/board.templ`, Line: 35, Col: 17}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</p></header><div class=\"new-thread-container\"><button _=\"on click hide me then show #newThreadForm\" id=\"newThreadBtn\">[New Thread]</button>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
@@ -80,7 +110,7 @@ func Comfy() templ.Component {
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }
+2 -3
View File
@@ -19,9 +19,8 @@ templ Layout() {
</span> </span>
<span> <span>
[ [
<a href="/comfy">comfy</a> <a href="/comfy">comfy</a> /
/ <a href="/r9k">r9k</a>
<a href="#">r9k</a>
] ]
</span> </span>
</div> </div>
+1 -1
View File
@@ -29,7 +29,7 @@ func Layout() templ.Component {
templ_7745c5c3_Var1 = templ.NopComponent templ_7745c5c3_Var1 = templ.NopComponent
} }
ctx = templ.ClearChildren(ctx) ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>Comfychan</title><script src=\"https://unpkg.com/hyperscript.org@0.9.14\"></script><link rel=\"stylesheet\" href=\"/static/reset.css\"><link rel=\"stylesheet\" href=\"/static/index.css\"></head><body><div id=\"boardList\"><span>[ <a href=\"/\">index</a> ]</span> <span>[ <a href=\"/comfy\">comfy</a> / <a href=\"#\">r9k</a> ]</span></div>") templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>Comfychan</title><script src=\"https://unpkg.com/hyperscript.org@0.9.14\"></script><link rel=\"stylesheet\" href=\"/static/reset.css\"><link rel=\"stylesheet\" href=\"/static/index.css\"></head><body><div id=\"boardList\"><span>[ <a href=\"/\">index</a> ]</span> <span>[ <a href=\"/comfy\">comfy</a> / <a href=\"/r9k\">r9k</a> ]</span></div>")
if templ_7745c5c3_Err != nil { if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err return templ_7745c5c3_Err
} }