Files
weatherreporter/internal/reporttemplate/reporttemplate.go

65 lines
1.7 KiB
Go

// Package reporttemplate provides embedded Markdown templates and partials.
package reporttemplate
import (
"bytes"
"embed"
"fmt"
"text/template"
)
//go:embed templates/*.md.tmpl templates/partials/*.md.tmpl
var assets embed.FS
var templates = map[string]string{
"daily": "templates/daily.md.tmpl",
"hourly": "templates/hourly.md.tmpl",
"today": "templates/today.md.tmpl",
"tomorrow": "templates/tomorrow.md.tmpl",
}
var templatePartials = []string{
"templates/partials/alert_digest.md.tmpl",
"templates/partials/daypart_forecast.md.tmpl",
"templates/partials/precipitation_timing.md.tmpl",
"templates/partials/today_daypart_forecast.md.tmpl",
}
func Template(id string) (string, error) {
path, ok := templates[id]
if !ok {
return "", fmt.Errorf("unknown report template %q", id)
}
data, err := assets.ReadFile(path)
if err != nil {
return "", fmt.Errorf("read report template %q: %w", id, err)
}
return string(data), nil
}
func Render(id string, data any) ([]byte, error) {
source, err := Template(id)
if err != nil {
return nil, err
}
tmpl, err := template.New(id).Funcs(templateFuncs()).Option("missingkey=error").Parse(source)
if err != nil {
return nil, fmt.Errorf("parse report template %q: %w", id, err)
}
for _, path := range templatePartials {
partial, err := assets.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read report template partial %q: %w", path, err)
}
tmpl, err = tmpl.Parse(string(partial))
if err != nil {
return nil, fmt.Errorf("parse report template partial %q: %w", path, err)
}
}
var out bytes.Buffer
if err := tmpl.Execute(&out, data); err != nil {
return nil, fmt.Errorf("render report template %q: %w", id, err)
}
return out.Bytes(), nil
}