Skip to content

Instantly share code, notes, and snippets.

@nicolasparada
Last active October 11, 2023 19:54
Show Gist options
  • Save nicolasparada/9a838f59cd932cc8ce84e438d97842c2 to your computer and use it in GitHub Desktop.
Save nicolasparada/9a838f59cd932cc8ce84e438d97842c2 to your computer and use it in GitHub Desktop.
Golang partial rendering component
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Golang Counter Component</title>
<link rel="shortcut icon" href="data:,">
<style>
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
}
}
</style>
</head>
<body>
<main class="container">
<div>
<p>Count: {{block "count" .}}<span id="count">{{.}}</span>{{end}}</p>
<div>
<form method="POST" action="/increase">
<button title="Increase">+</button>
</form>
<form method="POST" action="/decrease">
<button title="Decrease">-</button>
</form>
</div>
</div>
</main>
<script>
for (const form of Array.from(document.querySelectorAll('form'))) {
form.addEventListener("submit", function onSubmit(ev) {
ev.preventDefault()
const data = new FormData(form)
data.append("_want_block", "true")
fetch(form.action, { method: form.method, body: data })
.then(resp => resp.text()).then(html => {
const doc = new DOMParser().parseFromString(html, "text/html")
for (const newEl of Array.from(doc.body.children)) {
const oldEl = document.getElementById(newEl.id)
if (oldEl !== null) {
oldEl.outerHTML = newEl.outerHTML
}
}
})
})
}
</script>
</body>
</html>
package main
import (
"embed"
"fmt"
"log"
"net/http"
"os"
"text/template"
)
//go:embed counter.html.tmpl
var fs embed.FS
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
var count int64
func run() error {
tmpl, err := template.ParseFS(fs, "counter.html.tmpl")
if err != nil {
return fmt.Errorf("coult not parse template: %w", err)
}
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, count)
})
mux.HandleFunc("/increase", func(w http.ResponseWriter, r *http.Request) {
count++
if r.PostFormValue("_want_block") == "true" {
tmpl.ExecuteTemplate(w, "count", count)
return
}
http.Redirect(w, r, r.Referer(), http.StatusFound)
})
mux.HandleFunc("/decrease", func(w http.ResponseWriter, r *http.Request) {
count--
if r.PostFormValue("_want_block") == "true" {
tmpl.ExecuteTemplate(w, "count", count)
return
}
http.Redirect(w, r, r.Referer(), http.StatusFound)
})
log.Println("starting server at http://localhost:4000")
return http.ListenAndServe(":4000", mux)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment