❯ go-clikit
v0.10.0 pkg.go.dev ↗

packages › local web › localweb/page

page

import "github.com/GSI-HPC/go-clikit/localweb/page"

Keep the templates of a page in one set, render a fragment the same everywhere, and answer the requests of htmx.

since v0.9.0 imports: no package of the kit decisions 35 · 41
The place of localweb/page in go-clikit: the packages it imports, and the packages that import it.termtextprogressdisplaycliprogressprogresstestmcpprogresseventlogfanoutfanouttestclioutdoctorfsutilcobratreecobratreetestlocalwebsessionsselocalwebtestlaunchassetspagehtmx

A program parses its templates into one page.Set. Each page and each fragment is a block of its own name. So a fragment renders the same in the page, in the answer to htmx, and in an event of the stream.

{{define "layout"}}<main>{{include .Content .}}</main>{{end}}
{{define "page-hosts"}}<table>{{include "hosts-table" .}}</table>{{end}}
fsys := fstest.MapFS{"ui.html": &fstest.MapFile{Data: []byte(
	`{{define "layout"}}<main>{{include .Content .}}</main>{{end}}` +
		`{{define "page-hosts"}}<table>{{include "hosts-table" .}}</table>{{end}}` +
		`{{define "hosts-table"}}{{range .Hosts}}<tr><td>{{.}}</td></tr>{{end}}{{end}}`)}}
set, err := page.Parse(fsys, page.Options{}, "*.html")
if err != nil {
	fmt.Println(err)
	return
}

w := httptest.NewRecorder()
data := map[string]any{"Content": "page-hosts", "Hosts": []string{"node1", "<node2>"}}
if err := set.Respond(w, http.StatusOK, "layout", data); err != nil {
	fmt.Println(err)
	return
}
fmt.Println(w.Code, w.Header().Get("Content-Type"))
fmt.Println(w.Body)
200 text/html; charset=utf-8
<main><table><tr><td>node1</td></tr><tr><td>&lt;node2&gt;</td></tr></table></main>
ExampleSet_Respond in localweb/page/example_test.go. CI runs it and checks its output.
NameWhat it does
page.Parse, page.Setthe templates in one set; include runs a block by name
page.Set.Respondrenders the whole block before it writes anything
page.IsHTMX, page.Redirect, page.Retargetthe requests and headers of htmx
page.MaxIncludeDeptha block that includes itself fails, and does not overflow the stack
NOTE

Check at the start of the program that each block it names is there, with Set.Has.