> ## Documentation Index
> Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Templates

> Understanding Go template syntax and data access

This guide covers everything you need to know about writing templates in Mizu's view system. We'll explore Go's template syntax, how data flows through your templates, and common patterns.

## Template Basics

Mizu uses Go's standard `html/template` package. Templates are HTML files with special markers (`{{` and `}}`) for dynamic content.

```html theme={null}
<!-- views/pages/home.html -->
<h1>Hello, {{.Data.Name}}!</h1>
<p>Welcome to our site.</p>
```

## Accessing Data

In Mizu templates, your data is wrapped in a structure. Access your data using `.Data`:

```go theme={null}
// In your handler:
view.Render(c, "home", view.Data{
    "Title":   "Welcome",
    "User":    user,
    "Items":   items,
})
```

```html theme={null}
<!-- In your template: -->
<h1>{{.Data.Title}}</h1>
<p>Hello, {{.Data.User.Name}}</p>
```

### The Template Data Structure

Templates receive this structure:

| Field          | Description                   | Available In      |
| -------------- | ----------------------------- | ----------------- |
| `.Page.Name`   | Template name (e.g., "home")  | Pages and Layouts |
| `.Page.Layout` | Layout name (e.g., "default") | Pages and Layouts |
| `.Data`        | Your data from the handler    | Pages and Layouts |
| `.Content`     | Rendered page content         | Layouts only      |

## Go Template Syntax

### Outputting Values

Use `.Data.` to access your data:

```html theme={null}
<!-- Simple value -->
<h1>{{.Data.Title}}</h1>

<!-- Nested struct field -->
<p>Author: {{.Data.Post.Author.Name}}</p>

<!-- Map key -->
<p>Setting: {{.Data.Settings.theme}}</p>
```

### Conditions

Use `if` to show content conditionally:

```html theme={null}
{{if .Data.LoggedIn}}
    <p>Welcome back!</p>
{{else}}
    <p>Please log in.</p>
{{end}}

{{if .Data.Error}}
    <div class="error">{{.Data.Error}}</div>
{{end}}
```

### Comparison Operators

Go templates provide comparison functions:

| Function | Description           | Example                           |
| -------- | --------------------- | --------------------------------- |
| `eq`     | Equal                 | `{{if eq .Data.Status "active"}}` |
| `ne`     | Not equal             | `{{if ne .Data.Count 0}}`         |
| `lt`     | Less than             | `{{if lt .Data.Price 100}}`       |
| `le`     | Less than or equal    | `{{if le .Data.Stock 5}}`         |
| `gt`     | Greater than          | `{{if gt .Data.Price 100}}`       |
| `ge`     | Greater than or equal | `{{if ge .Data.Age 18}}`          |

```html theme={null}
{{if eq .Data.Status "active"}}Active{{end}}
{{if ne .Data.Count 0}}Has items{{end}}
{{if gt .Data.Price 100}}Premium{{end}}
{{if le .Data.Stock 5}}Low stock{{end}}
```

### Boolean Logic

Combine conditions with `and`, `or`, and `not`:

```html theme={null}
{{if and .Data.LoggedIn .Data.IsAdmin}}
    Admin controls
{{end}}

{{if or .Data.Error .Data.Warning}}
    <div class="alert">Check messages</div>
{{end}}

{{if not .Data.Disabled}}
    <button>Click me</button>
{{end}}
```

### Loops

Use `range` to iterate over slices, arrays, or maps:

```html theme={null}
<!-- Loop over slice -->
<ul>
    {{range .Data.Items}}
    <li>{{.}}</li>
    {{end}}
</ul>

<!-- With index -->
<ul>
    {{range $index, $item := .Data.Items}}
    <li>{{$index}}: {{$item}}</li>
    {{end}}
</ul>

<!-- Empty case -->
{{range .Data.Items}}
    <li>{{.}}</li>
{{else}}
    <li>No items found.</li>
{{end}}
```

### Looping Over Structs

When ranging over a slice of structs:

```html theme={null}
{{range .Data.Users}}
    <!-- Inside range, . is the current user -->
    <div class="user">
        <h3>{{.Name}}</h3>
        <p>{{.Email}}</p>
    </div>
{{end}}
```

### Looping Over Maps

```html theme={null}
{{range $key, $value := .Data.Settings}}
    <p>{{$key}}: {{$value}}</p>
{{end}}
```

### Variables

Assign values to variables with `:=`:

```html theme={null}
{{$name := .Data.User.Name}}
<p>Hello, {{$name}}!</p>

{{$fullName := printf "%s %s" .Data.FirstName .Data.LastName}}
<p>{{$fullName}}</p>
```

### The Root Context (\$)

Inside a `range` loop, `.` refers to the current item. Use `$` to access the root context:

```html theme={null}
{{range .Data.Users}}
    <p>{{.Name}}</p>
    {{if $.Data.ShowEmail}}
        <p>{{.Email}}</p>
    {{end}}
{{end}}
```

`$` always refers to the original data passed to the template.

### Pipelines

Chain operations with `|`:

```html theme={null}
<!-- Apply function to value -->
<p>{{.Data.Name | upper}}</p>

<!-- Chain multiple functions -->
<p>{{.Data.Title | lower | trim}}</p>
```

### Comments

Template comments are stripped from output:

```html theme={null}
{{/* This comment won't appear in the HTML */}}
<p>Visible content</p>
```

### Whitespace Control

Use `-` to trim whitespace:

```html theme={null}
{{- .Data.Name -}}    <!-- Trims whitespace before and after -->
{{- .Data.Name}}      <!-- Trims whitespace before -->
{{.Data.Name -}}      <!-- Trims whitespace after -->
```

This is useful for keeping your HTML clean:

```html theme={null}
<ul>
    {{- range .Data.Items}}
    <li>{{.}}</li>
    {{- end}}
</ul>
```

## Layouts and Pages

### Layout Structure

Layouts use `{{.Content}}` to include the rendered page:

```html theme={null}
<!-- views/layouts/default.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.Data.Title}}</title>
</head>
<body>
    <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
    </nav>
    <main>
        {{.Content}}
    </main>
    <footer>
        Copyright 2024
    </footer>
</body>
</html>
```

### Page Structure

Pages are simple - just write HTML with template expressions:

```html theme={null}
<!-- views/pages/home.html -->
<h1>Welcome, {{.Data.Name}}!</h1>
<p>This is the home page.</p>
```

The page content is rendered first, then inserted into the layout's `{{.Content}}`.

## Common Patterns

### Conditional Classes

```html theme={null}
<div class="card {{if .Data.Featured}}card-featured{{end}}">
    ...
</div>

<!-- Multiple conditional classes -->
<button class="btn {{if .Data.Primary}}btn-primary{{else}}btn-secondary{{end}} {{if .Data.Large}}btn-lg{{end}}">
    {{.Data.Label}}
</button>
```

### Dynamic Attributes

```html theme={null}
<input
    type="text"
    name="{{.Data.Name}}"
    value="{{.Data.Value}}"
    {{if .Data.Required}}required{{end}}
    {{if .Data.Disabled}}disabled{{end}}
>
```

### Safe HTML Output

By default, Go templates escape HTML to prevent XSS attacks:

```html theme={null}
<!-- Escaped (safe) - shows HTML as text -->
<div>{{.Data.Content}}</div>
<!-- If .Data.Content is "<b>bold</b>", outputs: &lt;b&gt;bold&lt;/b&gt; -->
```

To output raw HTML (use only with trusted content!):

```go theme={null}
import "html/template"

view.Data{
    "Content": template.HTML("<b>bold</b>"),
}
```

```html theme={null}
<div>{{.Data.Content}}</div>
<!-- Now outputs: <b>bold</b> -->
```

### Empty/Nil Checks

```html theme={null}
<!-- Check for empty string -->
{{if .Data.Description}}
    <p>{{.Data.Description}}</p>
{{end}}

<!-- Check slice length -->
{{if .Data.Items}}
    <ul>
        {{range .Data.Items}}
        <li>{{.}}</li>
        {{end}}
    </ul>
{{else}}
    <p>No items found.</p>
{{end}}
```

### Building Links

```html theme={null}
<a href="/users/{{.Data.User.ID}}">View Profile</a>
<a href="/posts?page={{.Data.Page}}">Next Page</a>
```

### Formatting Numbers and Dates

Use custom functions or `printf`:

```html theme={null}
<p>Price: ${{printf "%.2f" .Data.Price}}</p>
<p>Count: {{printf "%d" .Data.Count}}</p>
```

For dates, either format in Go or use a custom function:

```go theme={null}
view.Data{
    "FormattedDate": time.Now().Format("January 2, 2006"),
}
```

Or add a custom function:

```go theme={null}
view.Config{
    Funcs: template.FuncMap{
        "formatDate": func(t time.Time) string {
            return t.Format("Jan 2, 2006")
        },
    },
}
```

```html theme={null}
<p>Published: {{formatDate .Data.PublishedAt}}</p>
```

## Debugging Templates

### Print Values

Use `printf` with `%#v` to see the Go syntax representation:

```html theme={null}
<pre>{{printf "%#v" .Data}}</pre>
```

### Check Types

```html theme={null}
<p>Type: {{printf "%T" .Data.Items}}</p>
```

### Enable Development Mode

For detailed error messages with line numbers:

```go theme={null}
view.New(view.Config{
    Development: true,
})
```

## Best Practices

### 1. Keep Templates Simple

Put complex logic in Go handlers, not templates:

```go theme={null}
// Good: logic in handler
isVIP := user.TotalPurchases > 1000 && user.MemberSince.Before(cutoff)
view.Data{"IsVIP": isVIP}
```

```html theme={null}
<!-- Template just uses the result -->
{{if .Data.IsVIP}}VIP Member{{end}}
```

### 2. Use Meaningful Variable Names

```html theme={null}
{{range $user := .Data.Users}}
    <p>{{$user.Name}}</p>
{{end}}
```

### 3. Document Expected Data

Add comments at the top of templates:

```html theme={null}
{{/*
    Expected data:
    - Title: string
    - User: {Name, Email}
    - Posts: []Post
*/}}
```

### 4. Escape User Input

Always let Go's default escaping protect against XSS. Only use `template.HTML` for content you trust completely.

### 5. Use Whitespace Trimming

Keep generated HTML clean:

```html theme={null}
<ul>
{{- range .Data.Items}}
    <li>{{.}}</li>
{{- end}}
</ul>
```
