Skip to content

Latest commit

 

History

History
142 lines (103 loc) · 3.8 KB

File metadata and controls

142 lines (103 loc) · 3.8 KB

Quick Start

Serve HTML from templates with routes generated by Muxt.

Prerequisites: Go 1.26 or later, go install github.com/typelate/muxt@latest, and $(go env GOPATH)/bin on your PATH.

Step 1: Create the module

mkdir hello-muxt && cd hello-muxt
go mod init example.com/hello-muxt

Step 2: Create main.go

package main

import (
	"embed"
	"html/template"
	"log"
	"net/http"
)

//go:embed *.gohtml
var templateFiles embed.FS

//go:generate muxt generate
var templates = template.Must(template.ParseFS(templateFiles, "*.gohtml"))

func main() {
	mux := http.NewServeMux()
	TemplateRoutes(mux, nil)
	log.Fatal(http.ListenAndServe(":8080", mux))
}

Muxt reads the package-level templates variable. TemplateRoutes takes the receiver whose methods routes call. No route here calls one, so RoutesReceiver is empty and nil satisfies it.

Step 3: Create index.gohtml

{{define "GET /"}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello</title></head>
<body>
  <h1>Hello from Muxt!</h1>
</body>
</html>
{{end}}

The template name is the route.

Step 4: Generate and run

go generate && muxt check && go run .

muxt check type-checks each template against its handler (check). Open http://localhost:8080.

go generate wrote template_routes.go. Search it for HandleFunc: one call per route template, the template name as the pattern.

Step 5: Read the request in a template

The template data carries the request as .Request. Add to index.gohtml:

{{define "GET /hello/{name}"}}
<h1>Hello, {{.Request.PathValue "name"}}!</h1>
{{with .Request.URL.Query.Get "from"}}<p>Sent from {{.}}.</p>{{end}}
{{end}}
go generate && muxt check && go run .

template_routes.go also gained ReadHelloByName, a URL builder (.Path).

Step 6: Swap a fragment with htmz

Add a fragment route to index.gohtml:

{{define "GET /number"}}
<div id="big-number">
  <p style="font-size:8rem;text-align:center">{{.Request.URL.Query.Get "n"}}</p>
</div>
{{end}}

Replace the GET / template:

{{define "GET /"}}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello</title></head>
<body>
  <h1>Hello from Muxt!</h1>

  <form method="get" action="/number#big-number" target="htmz">
    <input type="number" name="n" value="42">
    <button>Show</button>
  </form>

  <div id="big-number">
    <p style="font-size:8rem;text-align:center">?</p>
  </div>

  <iframe hidden name=htmz onload="setTimeout(()=>document.querySelector(contentWindow.location.hash||null)?.replaceWith(...contentDocument.body.childNodes))"></iframe>
</body>
</html>
{{end}}

target="htmz" names the iframe, and the #big-number fragment names the element htmz replaces.

go generate && muxt check && go run .

Open http://localhost:8080, type a number, click Show. The GET /number handler in template_routes.go is identical in shape to GET /.

Next

Routes here read .Request because none calls a method. Name one and the template reads its result as .Result (call results):

{{define "GET /square/{n} Square(ctx, n)"}}{{.Result}}{{end}}