Guide / 03 — Templates

Syntax & Expressions

.stew files are HTML templates augmented with Go logic. They are compiled by the Stew-Lang compiler into idiomatic Go code before being compiled by Go.

Expressions {{ }}

Double curly braces evaluate a Go expression and display it in the HTML. The value is automatically escaped (HTML-safe).

<!-- Simple value -->
<p>{{ data.Params["id"] }}</p>

<!-- Inline Go expression -->
<p>{{ strings.ToUpper(data.URL) }}</p>

<!-- Variable declared in goscript -->
<h1>{{ title }}</h1>
Raw unescaped HTML: Use {{ raw(expr) }} to inject raw HTML (dangerous — reserved for SDK usage).

Conditional {{ if }}

{{ if data.Store["user"] != nil }}
    <p>Logged in as {{ data.Store["user"] }}</p>
{{ else }}
    <p><a href="/login">Sign in</a></p>
{{ end }}

The expression after if is pure Go. {{ else }} is optional. Close with {{ end }}.

Loop {{ each }}

<!-- Syntax: each <slice> as <item>, <index> -->
{{ each data.Users as user, i }}
    <div>
        <span>{{ i }}.</span>
        <strong>{{ user.Name }}</strong>
    </div>
{{ end }}

Generates a for i, user := range data.Users in Go. The index is optional.

<goscript> Blocks

The <goscript> blocks (with no attribute or server) contain Go logic executed on the **server** during page rendering. They are excluded from the final HTML.

<goscript>
    import "strconv"
    import "fmt"

    count := 0
    if c := data.Query.Get("count"); c != "" {
        count, _ = strconv.Atoi(c)
    }
    title := fmt.Sprintf("Page %d", count)
</goscript>

<h1>{{ title }}</h1>
<p>Count: {{ count }}</p>

Automatic imports: The compiler analyzes your Go code. If it detects usage of fmt. or html., it automatically adds the corresponding imports. For any other package (e.g., strings, os), you must manually import it within a <goscript> block.

Variables: Declared with := in a server block, they are injected as local variables in the rendering function and are accessible throughout the template.

Struct types: Declarations like type Foo struct { ... } are extracted and placed at the top level of the generated Go package, making them accessible globally within the file.

HTML Comments

<!-- This comment is preserved as-is in the HTML output -->

Standard HTML comments are passed through to the generated output.