Implement dynamically getting board data
This commit is contained in:
+1
-1
@@ -1 +1 @@
|
|||||||
internal/db/comfychan.db
|
internal/database/comfychan.db
|
||||||
|
|||||||
@@ -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
@@ -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")
|
||||||
|
|||||||
@@ -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,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.
@@ -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()
|
||||||
|
}
|
||||||
@@ -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 +0,0 @@
|
|||||||
package db
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package internal
|
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user