commit f6bfd1f7ab348cf2c00c74927dc290fd4ce36cd2 Author: Pedro Pérez Date: Fri Dec 5 01:13:13 2025 +0100 add basic and htmx examples diff --git a/basic/go.mod b/basic/go.mod new file mode 100644 index 0000000..bd353b3 --- /dev/null +++ b/basic/go.mod @@ -0,0 +1,5 @@ +module basic + +go 1.25.2 + +require github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1 diff --git a/basic/go.sum b/basic/go.sum new file mode 100644 index 0000000..839a2ad --- /dev/null +++ b/basic/go.sum @@ -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= diff --git a/basic/main.go b/basic/main.go new file mode 100644 index 0000000..931ca82 --- /dev/null +++ b/basic/main.go @@ -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") + } +} diff --git a/basic/templates/index.html b/basic/templates/index.html new file mode 100644 index 0000000..aac8214 --- /dev/null +++ b/basic/templates/index.html @@ -0,0 +1,12 @@ + + + + + + + + + + hello world + + diff --git a/htmx/go.mod b/htmx/go.mod new file mode 100644 index 0000000..8077da4 --- /dev/null +++ b/htmx/go.mod @@ -0,0 +1,5 @@ +module htmx + +go 1.25.2 + +require github.com/zepyrshut/hrender v0.0.0-20251204145920-50fdd9cb5ff1 diff --git a/htmx/go.sum b/htmx/go.sum new file mode 100644 index 0000000..051a724 --- /dev/null +++ b/htmx/go.sum @@ -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= diff --git a/htmx/main.go b/htmx/main.go new file mode 100644 index 0000000..a22a793 --- /dev/null +++ b/htmx/main.go @@ -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") + } +} diff --git a/htmx/templates/fragments/todo-row-edit.html b/htmx/templates/fragments/todo-row-edit.html new file mode 100644 index 0000000..3a0cfa2 --- /dev/null +++ b/htmx/templates/fragments/todo-row-edit.html @@ -0,0 +1,6 @@ +
  • +
    + +
    +
  • + diff --git a/htmx/templates/fragments/todo-row.html b/htmx/templates/fragments/todo-row.html new file mode 100644 index 0000000..1f8f2f0 --- /dev/null +++ b/htmx/templates/fragments/todo-row.html @@ -0,0 +1,10 @@ +
  • + +
  • + diff --git a/htmx/templates/fragments/todo-widget.html b/htmx/templates/fragments/todo-widget.html new file mode 100644 index 0000000..4eff19d --- /dev/null +++ b/htmx/templates/fragments/todo-widget.html @@ -0,0 +1,9 @@ +

    Listado de tareas

    + + + +
      + {{ range .TodoList }} {{ template "fragments/todo-row" . }} {{ end }} +
    diff --git a/htmx/templates/pages/index.html b/htmx/templates/pages/index.html new file mode 100644 index 0000000..70391b2 --- /dev/null +++ b/htmx/templates/pages/index.html @@ -0,0 +1,12 @@ + + + + + + Lista de tareas + + + +
    Cargando...
    + +