add basic and htmx examples

This commit is contained in:
Pedro Pérez 2025-12-05 01:13:13 +01:00
commit f6bfd1f7ab
11 changed files with 242 additions and 0 deletions

5
basic/go.mod Normal file
View File

@ -0,0 +1,5 @@
module basic
go 1.25.2
require github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1

2
basic/go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1 h1:Zpay8/pWw++3B/QXsGbF3eTI1z2tGynguQWAnERIg9c=
github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1/go.mod h1:KxR0Cisj52sFFxMTm3o+OJWBqP/khUpA1bjjc49iAiM=

30
basic/main.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"log"
"net/http"
"os"
"github.com/zepyrshut/hrender"
)
func main() {
templatesFS := os.DirFS("./templates")
h := hrender.NewHTMLRender(templatesFS, false)
mux := http.NewServeMux()
mux.Handle("GET /", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
err := h.Render(w, "index", hrender.H{})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
log.Println("server started on port 8080")
err := http.ListenAndServe(":8080", mux)
if err != nil {
panic("server cannot start")
}
}

View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
<link href="css/style.css" rel="stylesheet" />
</head>
<body>
hello world
</body>
</html>

5
htmx/go.mod Normal file
View File

@ -0,0 +1,5 @@
module htmx
go 1.25.2
require github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1

4
htmx/go.sum Normal file
View File

@ -0,0 +1,4 @@
github.com/zepyrshut/hrender v0.0.0-20251204134824-5eb5dc8eaf21 h1:jUfJj+Ymdd9krHUt3YzBxR5kFoRAp+RD3u4Yir/KSGQ=
github.com/zepyrshut/hrender v0.0.0-20251204134824-5eb5dc8eaf21/go.mod h1:KxR0Cisj52sFFxMTm3o+OJWBqP/khUpA1bjjc49iAiM=
github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1 h1:Zpay8/pWw++3B/QXsGbF3eTI1z2tGynguQWAnERIg9c=
github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1/go.mod h1:KxR0Cisj52sFFxMTm3o+OJWBqP/khUpA1bjjc49iAiM=

147
htmx/main.go Normal file
View File

@ -0,0 +1,147 @@
package main
import (
"log"
"net/http"
"os"
"sort"
"strconv"
"github.com/zepyrshut/hrender"
)
type TodoList struct {
ID int
Name string
Completed bool
}
var todoList = []TodoList{
{
ID: 1,
Name: "Sacar a la perra",
Completed: false,
},
{
ID: 2,
Name: "Limpiar la casa",
Completed: false,
},
{
ID: 3,
Name: "Ir al supermercado",
Completed: false,
},
}
func main() {
templatesFS := os.DirFS("./templates")
h := hrender.NewHTMLRender(templatesFS, false)
mux := http.NewServeMux()
mux.Handle("GET /", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
err := h.Render(w, "pages/index", hrender.H{})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
mux.Handle("GET /todo", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
sort.Slice(todoList, func(i, j int) bool {
return todoList[i].ID > todoList[j].ID
})
err := h.Render(w, "fragments/todo-widget", hrender.H{
"TodoList": todoList,
})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
mux.Handle("GET /todo/new", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
err := h.Render(w, "fragments/todo-row-edit", hrender.H{})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
mux.Handle("POST /todo", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
http.Error(w, "bad request", http.StatusBadRequest)
return
}
newID := 0
sort.Slice(todoList, func(i, j int) bool {
return todoList[i].ID > todoList[j].ID
})
newID = todoList[0].ID + 1
log.Println(todoList[len(todoList)-1].ID)
log.Println(todoList)
newItem := TodoList{
ID: newID,
Name: r.FormValue("name"),
Completed: false,
}
todoList = append(todoList, newItem)
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
err = h.Render(w, "fragments/todo-row", hrender.H{
"ID": newID,
"Name": newItem.Name,
"Completed": false,
})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
mux.Handle("PATCH /todo/{id}/completed", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
idStr := r.PathValue("id")
id, err := strconv.Atoi(idStr)
if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest)
return
}
var foundItem *TodoList
for i := range todoList {
if todoList[i].ID == id {
todoList[i].Completed = true
foundItem = &todoList[i]
break
}
}
if foundItem == nil {
http.Error(w, "item not found", http.StatusNotFound)
return
}
w.Header().Set(hrender.ContentType, hrender.ContentTextHTMLUTF8)
err = h.Render(w, "fragments/todo-row", hrender.H{
"ID": foundItem.ID,
"Name": foundItem.Name,
"Completed": true,
})
if err != nil {
http.Error(w, "error loading template", http.StatusInternalServerError)
}
}))
log.Println("server started on port 8080")
err := http.ListenAndServe(":8080", mux)
if err != nil {
panic("server cannot start")
}
}

View File

@ -0,0 +1,6 @@
<li>
<form hx-post="/todo" hx-target="closest li" hx-swap="outerHTML">
<input type="text" name="name" placeholder="Nueva tarea..." autofocus />
</form>
</li>

View File

@ -0,0 +1,10 @@
<li>
<button
hx-patch="/todo/{{.ID}}/completed"
hx-target="closest li"
hx-swap="outerHTML"
>
{{ .ID }} {{ .Name }} - {{ .Completed }}
</button>
</li>

View File

@ -0,0 +1,9 @@
<h2>Listado de tareas</h2>
<button hx-get="/todo/new" hx-target="#todo-list-body" hx-swap="afterbegin">
Nueva tarea
</button>
<ol id="todo-list-body">
{{ range .TodoList }} {{ template "fragments/todo-row" . }} {{ end }}
</ol>

View File

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Lista de tareas</title>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js"></script>
</head>
<body>
<div hx-get="/todo" hx-trigger="load" hx-swap="outerHTML">Cargando...</div>
</body>
</html>