templates: Share fragments
This commit is contained in:
parent
dd7be3f520
commit
d64e6f8ec3
12 changed files with 111 additions and 93 deletions
|
|
@ -1,7 +1,6 @@
|
|||
package static
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
)
|
||||
|
||||
|
|
@ -25,26 +24,25 @@ type Assets struct {
|
|||
//go:generate node build.mjs HomeHome ComponentsIndex ControlIndex ControlInstance
|
||||
|
||||
// MustParse parses a new template from the given source
|
||||
// and registers the Asset functions to it.
|
||||
// See [Assets.RegisterFuncs].
|
||||
// and calls [RegisterAssoc] on it.
|
||||
func (assets *Assets) MustParse(t *template.Template, value string) *template.Template {
|
||||
if t == nil {
|
||||
t = template.New("")
|
||||
}
|
||||
return template.Must(assets.RegisterFuncs(t).Parse(value))
|
||||
t = template.Must(t.Parse(value))
|
||||
assets.RegisterAssoc(t)
|
||||
return t
|
||||
}
|
||||
|
||||
// RegisterFuncs registers three new template functions called "JS", "CSS" and "json".
|
||||
//
|
||||
// "JS" and "CSS" take no arguments, and return appropriate tags to be inserted into html.
|
||||
// json takes a single argument of any type, and returns it's encoding as a string to be inserted into the page.
|
||||
func (assets *Assets) RegisterFuncs(t *template.Template) *template.Template {
|
||||
return t.Funcs(template.FuncMap{
|
||||
"JS": func() template.HTML { return template.HTML(assets.Scripts) },
|
||||
"CSS": func() template.HTML { return template.HTML(assets.Styles) },
|
||||
"json": func(data any) (string, error) {
|
||||
bytes, err := json.Marshal(data)
|
||||
return string(bytes), err
|
||||
},
|
||||
})
|
||||
// MustParseShared is like [MustParse], but creates a new SharedTemplate instead
|
||||
func (assets *Assets) MustParseShared(name string, value string) *template.Template {
|
||||
return assets.MustParse(NewSharedTemplate(name), value)
|
||||
}
|
||||
|
||||
// RegisterAssoc registers two new associated templates with t.
|
||||
//
|
||||
// The template "scripts" will render all script tags required.
|
||||
// The template "styles" will render all style tags required.
|
||||
//
|
||||
// If either template already exists, it will be overwritten.
|
||||
func (assets *Assets) RegisterAssoc(t *template.Template) {
|
||||
t.New("scripts").Parse(assets.Scripts)
|
||||
t.New("styles").Parse(assets.Styles)
|
||||
}
|
||||
|
|
|
|||
30
internal/dis/component/control/static/templates.go
Normal file
30
internal/dis/component/control/static/templates.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package static
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"html/template"
|
||||
)
|
||||
|
||||
//go:embed "templates/*.html"
|
||||
var templates embed.FS
|
||||
|
||||
var (
|
||||
shared *template.Template = template.Must(template.ParseFS(templates, "templates/*.html"))
|
||||
)
|
||||
|
||||
// NewSharedTemplate creates a new template with the given name.
|
||||
// It will be able to make use of shared templates as well as functions.
|
||||
func NewSharedTemplate(name string) *template.Template {
|
||||
new := template.New(name)
|
||||
new.Funcs(template.FuncMap{
|
||||
"json": func(data any) (string, error) {
|
||||
bytes, err := json.Marshal(data)
|
||||
return string(bytes), err
|
||||
},
|
||||
})
|
||||
for _, template := range shared.Templates() {
|
||||
new.AddParseTree(template.Tree.Name, template.Tree.Copy())
|
||||
}
|
||||
return new
|
||||
}
|
||||
33
internal/dis/component/control/static/templates/_base.html
Normal file
33
internal/dis/component/control/static/templates/_base.html
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{ block "block" . }}Distillery Control Page{{ end }}</title>
|
||||
{{ block "styles" . }}styles{{ end }}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1 id="top">{{ template "title" . }}</h1>
|
||||
{{ block "header/time" . }}
|
||||
{{ if .Time }}
|
||||
<small>Generated at <code class="date">{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}</code></small>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ block "header" . }}header{{ end }}
|
||||
</header>
|
||||
<main>
|
||||
<div class="pure-g">
|
||||
{{ block "content" . }}content{{ end }}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
{{ if .Time }}
|
||||
<footer>
|
||||
Generated at <code>{{ .Time }}</code>
|
||||
</footer>
|
||||
{{ end }}
|
||||
|
||||
{{ block "scripts" . }}scripts{{ end }}
|
||||
</body>
|
||||
Loading…
Add table
Add a link
Reference in a new issue