package content
import (
"fmt"
"html/template"
"strings"
"unicode/utf16"
"thermograph/frontend/internal/config"
"thermograph/frontend/internal/format"
)
// FuncMap builds the template helper set (the Jinja globals/filters
// content.py registered on its Environment). Pass it to render.New at boot —
// html/template resolves names at parse time.
//
// Unit-dependent helpers (temp, temp_bare) take the active unit as their
// FIRST argument: the Python scoped it in a ContextVar, but html/template
// FuncMaps are engine-global, so per-request state must arrive through the
// call. Every page context carries the active unit under the "unit" key
// (same value as "unit_default"), so template call sites are
// {{temp $.unit .high_f}} where Jinja had {{ temp(m.high_f) }}.
func FuncMap(cfg config.Config) template.FuncMap {
return template.FuncMap{
// temp / temp_bare / temp_class accept the loosely-typed values the
// templates hand them: nullable *float64 payload fields, plain
// float64s, and int literals (Jinja's {{ temp(-10) }}).
"temp": func(unit, f any) template.HTML {
return format.Temp(unitArg(unit), floatArg(f))
},
"temp_bare": func(unit, f any) template.HTML {
return format.TempBare(unitArg(unit), floatArg(f))
},
"temp_class": func(f any) string {
return format.TempClass(floatArg(f))
},
// The `ordinal` filter: {{ c.percentile|ordinal }} -> {{ordinal .percentile}}.
"ordinal": format.PctOrdinal,
// Search-engine ownership-verification tags, from env (empty
// when unset). No backend dependency — the same two variables the
// Python read, resolved once into config.
"head_verify": func() template.HTML {
return headVerifyHTML(cfg.GoogleVerify, cfg.BingVerify)
},
// Jinja's |tojson (glossary_term.html.j2's inline JSON-LD): JSON with
// the HTML-unsafe characters escaped so it can sit inside