Bygg en Todo-app med HTMX och Go đđŻ
Vad Ă€r HTMX och Go? đâ
HTMX Ă€r ett modernt JavaScript-bibliotek som lĂ„ter dig bygga dynamiska webbapplikationer med minimal JavaScript. IstĂ€llet för att skriva komplex frontend-kod kan du anvĂ€nda enkla HTML-attribut för att skapa interaktiva anvĂ€ndargrĂ€nssnitt! âĄïž
Go Ă€r ett programmeringssprĂ„k skapat av Google som Ă€r kĂ€nt för sin enkelhet och prestanda. Det Ă€r perfekt för att bygga webbservers och API:er! đč
go-templ Ă€r ett templating-bibliotek för Go som gör det enkelt att generera HTML pĂ„ serversidan. đ
Varför HTMX + Go? đ€â
- Enkelhet đ: Mindre kod, fĂ€rre beroenden och enklare att förstĂ„
- Prestanda âĄïž: Go Ă€r snabbt, och HTMX minimerar JavaScript-overhead
- Serverdriven đ„ïž: All din applikationslogik finns pĂ„ servern
- Progressiv förbĂ€ttring đ: Din app fungerar Ă€ven utan JavaScript
- Snabb utveckling đââïž: Fokusera pĂ„ funktionalitet istĂ€llet för komplexitet
Installation pĂ„ Windows đ§â
Steg 1: Installera Go đčâ
- GĂ„ till https://go.dev/dl/
- Ladda ner Go för Windows
- Kör installationsfilen och följ anvisningarna
- Verifiera installationen genom att öppna PowerShell och köra:
go version
Steg 2: Konfigurera din utvecklingsmiljö đ ïžâ
- Skapa en ny mapp för ditt projekt:
mkdir todo-htmx-go
cd todo-htmx-go
- Initialisera ett Go-projekt:
go mod init todo-app
Steg 3: Installera go-templ đŠâ
go install github.com/a-h/templ/cmd/templ@latest
Se till att din PATH inkluderar Go's bin-katalog! Om templ inte hittas, lÀgg till %USERPROFILE%\go\bin till din PATH.
Skapa din första server đâ
GrundlĂ€ggande serverstrukturâ
Skapa en fil som heter main.go:
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", homeHandler)
fmt.Println("Server startar pĂ„ :8080 đ")
http.ListenAndServe(":8080", nil)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "<h1>VĂ€lkommen till Todo-appen!</h1>")
}
Kör servern:
go run main.go
Ăppna din webblĂ€sare och gĂ„ till http://localhost:8080 đ
LĂ€gg till HTMX đšâ
Skapa en HTML-template med go-templâ
Skapa en fil som heter templates.templ:
package main
templ Layout() {
<!DOCTYPE html>
<html lang="sv">
<head>
<meta charset="UTF-8"/>
<title>Todo App</title>
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.todo-item { margin: 10px 0; }
</style>
</head>
<body>
<h1>Min Todo-lista đ</h1>
{ children... }
</body>
</html>
}
templ TodoList(todos []Todo) {
<div id="todo-list">
for _, todo := range todos {
@TodoItem(todo)
}
</div>
}
Efter att du skapat .templ filer, mÄste du generera Go-kod frÄn dem:
templ generate
Bygga Todo-funktionaliteten đ ïžâ
Definiera Todo-strukturenâ
LĂ€gg till i main.go:
type Todo struct {
ID int
Text string
Completed bool
}
var todos = []Todo{
{ID: 1, Text: "LĂ€r dig HTMX", Completed: false},
{ID: 2, Text: "Bygga en Go-server", Completed: false},
}
LĂ€gg till todo-formulĂ€râ
Utöka din templates.templ:
templ TodoForm() {
<form hx-post="/todos" hx-target="#todo-list" hx-swap="beforeend">
<input type="text" name="text" placeholder="Ny uppgift..." required/>
<button type="submit">LĂ€gg till â</button>
</form>
}
templ TodoItem(todo Todo) {
<div class="todo-item" id={ fmt.Sprintf("todo-%d", todo.ID) }>
<input type="checkbox"
hx-put={ fmt.Sprintf("/todos/%d/toggle", todo.ID) }
hx-target={ fmt.Sprintf("#todo-%d", todo.ID) }
hx-swap="outerHTML"
if todo.Completed { checked }/>
<span if todo.Completed { style="text-decoration: line-through;" }>
{ todo.Text }
</span>
<button hx-delete={ fmt.Sprintf("/todos/%d", todo.ID) }
hx-target={ fmt.Sprintf("#todo-%d", todo.ID) }
hx-swap="outerHTML">
Ta bort đïž
</button>
</div>
}
Implementera HTMX-endpoints đâ
LĂ€gg till nya routesâ
Uppdatera din main.go:
func main() {
http.HandleFunc("/", homeHandler)
http.HandleFunc("/todos", todosHandler)
http.HandleFunc("/todos/", todoHandler) // För individuella todos
fmt.Println("Server startar pĂ„ :8080 đ")
http.ListenAndServe(":8080", nil)
}
func todosHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case "POST":
// HÀmta text frÄn formulÀret
text := r.FormValue("text")
// Skapa ny todo
newTodo := Todo{
ID: len(todos) + 1,
Text: text,
}
todos = append(todos, newTodo)
// Returnera bara den nya todo-komponenten
TodoItem(newTodo).Render(r.Context(), w)
}
}
Hantera toggle och deleteâ
func todoHandler(w http.ResponseWriter, r *http.Request) {
// Extrahera ID frÄn URL:en
// /todos/1/toggle -> ["", "todos", "1", "toggle"]
parts := strings.Split(r.URL.Path, "/")
if len(parts) < 3 {
http.NotFound(w, r)
return
}
id, _ := strconv.Atoi(parts[2])
switch r.Method {
case "PUT":
// Toggle completed status
for i := range todos {
if todos[i].ID == id {
todos[i].Completed = !todos[i].Completed
TodoItem(todos[i]).Render(r.Context(), w)
return
}
}
case "DELETE":
// Ta bort todo
for i, todo := range todos {
if todo.ID == id {
todos = append(todos[:i], todos[i+1:]...)
return
}
}
}
}
Felsökning och tips đâ
Vanliga problemâ
-
"templ: command not found"
- Kontrollera att Go's bin-katalog finns i din PATH
- Kör:
go env GOPATHoch lÀgg till/bintill den sökvÀgen
-
Templates genereras inte
- Kör alltid
templ generateefter att du Àndrat.templfiler - Kontrollera att filnamnet slutar med
.templ
- Kör alltid
-
HTMX fungerar inte
- Ăppna utvecklarkonsolen (F12) och kolla efter JavaScript-fel
- Verifiera att HTMX laddas korrekt
Tips för vidare utveckling đĄâ
- Databaspersistens: AnvÀnd SQLite för att spara todos permanent
- CSS-styling: LÀgg till Tailwind CSS för snyggare design
- Validering: LÀgg till serverside-validering för formulÀr
- Fel-hantering: Implementera bÀttre felmeddelanden
- Animationer: AnvÀnd HTMX:s inbyggda övergÄngar
NĂ€sta steg đâ
Nu har du grunderna! HÀr Àr nÄgra idéer för att utöka din app:
- Filtrera todos: Visa endast oavslutade uppgifter
- Redigera text: Gör det möjligt att Àndra todo-texten
- Prioritering: LÀgg till prioritetsnivÄer
- Kategorier: Organisera todos i olika listor
- AnvÀndarkonton: LÀgg till inloggning och personliga listor
- HTMX dokumentation: https://htmx.org/docs/
- Go by Example: https://gobyexample.com/
- go-templ guide: https://templ.guide/