Skip to content

gotemplate: ordered.Map dot notation and range support #1237

Description

@zeroedin

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:

  1. 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"
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions