Problem
Go templates cannot traverse *ordered.Map with dot notation. Every data access from YAML files requires explicit oget calls:
Liquid: {{ site.data.pkg.version }}
Go tmpl: {{ oget (oget .site.data "pkg") "version" }}
This makes Go templates impractical for sites with complex data structures (like RHDS with tokens, CEM data, package info). Converting *ordered.Map to map[string]interface{} isn't an option because key ordering must be preserved for template iteration.
Proposed Solution
Teach the Go template engine to handle *ordered.Map natively:
- Dot notation: When Go's template engine resolves
.field on a value, check if the value is *ordered.Map and call .Get(field) instead of failing with "can't evaluate field"
- Range: When
{{ range }} encounters an *ordered.Map, iterate in insertion order yielding .Key / .Value pairs (same as orange but automatic)
This could be implemented via a custom reflect.Value wrapper or by preprocessing the template execution context.
Impact
Without this, Go templates are a second-class engine in Alloy. Any site using YAML data (which is every site) hits this wall when migrating from Liquid to Go templates. The oget workaround is functional but makes templates unreadable and defeats the purpose of offering Go templates as an alternative.
Attempted
We attempted a full RHDS site migration from Liquid to Go templates. Layouts converted cleanly (25 files). Content files with data access (65+ files) hit this wall — every {{ }} expression touching YAML data needs nested oget calls, making the migration impractical.
Problem
Go templates cannot traverse
*ordered.Mapwith dot notation. Every data access from YAML files requires explicitogetcalls:This makes Go templates impractical for sites with complex data structures (like RHDS with tokens, CEM data, package info). Converting
*ordered.Maptomap[string]interface{}isn't an option because key ordering must be preserved for template iteration.Proposed Solution
Teach the Go template engine to handle
*ordered.Mapnatively:.fieldon a value, check if the value is*ordered.Mapand call.Get(field)instead of failing with "can't evaluate field"{{ range }}encounters an*ordered.Map, iterate in insertion order yielding.Key/.Valuepairs (same asorangebut automatic)This could be implemented via a custom
reflect.Valuewrapper or by preprocessing the template execution context.Impact
Without this, Go templates are a second-class engine in Alloy. Any site using YAML data (which is every site) hits this wall when migrating from Liquid to Go templates. The
ogetworkaround is functional but makes templates unreadable and defeats the purpose of offering Go templates as an alternative.Attempted
We attempted a full RHDS site migration from Liquid to Go templates. Layouts converted cleanly (25 files). Content files with data access (65+ files) hit this wall — every
{{ }}expression touching YAML data needs nestedogetcalls, making the migration impractical.