Components

Components are reusable .gastro files in the components/ directory. They accept typed props and can render children via slots.

Defining a Component

A component uses gastro.Props() to declare its props type. The Props struct defines what the component accepts:

---
type Props struct {
    Title  string
    Author string
}

Title := gastro.Props().Title
Author := gastro.Props().Author
---
<article>
    <h2>{{ .Title }}</h2>
    <p>By {{ .Author }}</p>
</article>

gastro.Props() is a compile-time marker that tells the code generator this file is a component. The Props struct must be defined in the same frontmatter.

Computed Values

When you need derived values from multiple props, assign the whole struct first:

---
import "fmt"

type Props struct {
    Label string
    X     int
}

p := gastro.Props()
Label := p.Label
CX := fmt.Sprintf("%d", p.X + 135)
---
<text x="{{ .CX }}">{{ .Label }}</text>

Importing & Using Components

Import components in the frontmatter with the .gastro file extension. The identifier is the local name used in the template:

---
import (
    Layout "components/layout.gastro"
    PostCard "components/post-card.gastro"
)

ctx := gastro.Context()
---
{{ wrap Layout (dict "Title" "Home") }}
    {{ PostCard (dict "Title" "My Post" "Slug" "my-post") }}
{{ end }}

Prop Syntax

Props are passed as attributes on the component tag:

<!-- Template expression -->
{{ PostCard (dict "Title" .Title "Slug" .Slug) }}

<!-- String literal -->
{{ Layout (dict "Title" "About") }}

<!-- Pipe expression -->
{{ PostCard (dict "Date" (.CreatedAt | timeFormat "Jan 2, 2006")) }}
SyntaxMeaning
{.Expr}Go template expression, evaluated in parent's data context
"literal"String literal
{.Val | func "arg"}Pipe expression

Type Coercion

Gastro automatically coerces prop values to match struct field types:

Target TypeAccepted Values
stringAny value (converted via fmt.Sprintf)
boolbool, string ("true", "false")
intint, int64, float64, string (parsed)
float64float64, float32, int, string (parsed)

Slots

Slots let a component render content provided by its parent. Place <slot /> where children should appear:

---
type Props struct {
    Title string
}

Title := gastro.Props().Title
---
<html>
<head><title>{{ .Title }}</title></head>
<body>
    <nav>...</nav>
    <main>
        {{ .Children }}
    </main>
    <footer>...</footer>
</body>
</html>

The parent passes children by wrapping content in the component tags:

{{ wrap Layout (dict "Title" "Home") }}
    <h1>Welcome</h1>
    <p>This replaces the slot.</p>
{{ end }}

Children are rendered in the parent's data context, so they can reference the parent's template data. Only one unnamed slot is supported per component.