# RUITL Template Compilation Guide

This guide explains how to use RUITL's template compilation system to build type-safe, performant UI components using the `.ruitl` template syntax.

## Overview

RUITL's template compilation system transforms `.ruitl` template files into optimized Rust code at build time. This approach provides:

- **Natural HTML-like syntax** with Rust expressions
- **Compile-time validation** and type safety
- **Zero runtime overhead** - templates are compiled to native Rust
- **IDE support** with syntax highlighting and autocompletion
- **Component composition** with props and lifecycle management

## Architecture

```
.ruitl files → RUITL Parser → AST → Code Generator → .rs files → rustc → Binary
```

## Getting Started

### 1. Project Setup

Add RUITL to your `Cargo.toml`:

```toml
[dependencies]
ruitl = "0.1.0"
tokio = { version = "1.0", features = ["full"] }

[build-dependencies]
walkdir = "2.3"
```

Create a `build.rs` file in your project root:

```rust
// build.rs
fn main() {
    // RUITL templates will be automatically compiled
    println!("cargo:rerun-if-changed=templates");
}
```

### 2. Template Syntax

RUITL templates use a natural HTML-like syntax with Rust expressions.

#### Basic Template Structure

```ruitl
// templates/Button.ruitl

component Button {
    props {
        text: String,
        variant: String = "primary",
        disabled: bool = false,
    }
}

ruitl Button(props: ButtonProps) {
    <button
        class={format!("btn btn-{}", props.variant)}
        disabled?={props.disabled}
        type="button"
    >
        {props.text}
    </button>
}
```

#### Component Definition

Components are defined with the `component` keyword:

```ruitl
component MyComponent {
    props {
        // Required prop
        title: String,

        // Optional prop with default
        size: String = "medium",

        // Optional prop (nullable)
        description: String?,

        // Boolean with default
        visible: bool = true,

        // Complex types
        items: Vec<String>,
        metadata: HashMap<String, String>,
    }
}
```

#### Template Implementation

Templates are implemented with the `templ` keyword:

```ruitl
ruitl MyComponent(props: MyComponentProps) {
    <div class={format!("component component-{}", props.size)}>
        <h2>{props.title}</h2>

        if let Some(desc) = props.description {
            <p class="description">{desc}</p>
        }

        if props.visible {
            <ul class="items">
                for item in props.items {
                    <li class="item">{item}</li>
                }
            </ul>
        }
    </div>
}
```

### 3. Template Features

#### Expressions

Use `{}` for Rust expressions:

```ruitl
ruitl Example(props: ExampleProps) {
    <div>
        // Simple variable
        <p>{props.name}</p>

        // Method calls
        <p>{props.name.to_uppercase()}</p>

        // Complex expressions
        <p>{format!("Hello, {}!", props.name)}</p>

        // Arithmetic
        <p>Total: {props.price * props.quantity}</p>
    </div>
}
```

#### Conditional Rendering

Use `if` statements for conditional rendering:

```ruitl
ruitl ConditionalExample(props: ConditionalExampleProps) {
    <div>
        if props.show_header {
            <header>
                <h1>{props.title}</h1>
            </header>
        }

        if props.user.is_admin {
            <div class="admin-panel">Admin Controls</div>
        } else {
            <div class="user-panel">User Controls</div>
        }

        // Optional chaining
        if let Some(avatar) = props.user.avatar {
            <img src={avatar} alt="Avatar" />
        }
    </div>
}
```

#### Loops

Use `for` loops to render collections:

```ruitl
ruitl ListExample(props: ListExampleProps) {
    <ul class="list">
        for item in props.items {
            <li class="list-item">
                <span class="name">{item.name}</span>
                <span class="value">{item.value}</span>
            </li>
        }
    </ul>
}
```

#### Match Expressions

Use `match` for pattern matching:

```ruitl
ruitl StatusBadge(props: StatusBadgeProps) {
    <span class="status-badge">
        match props.status {
            "active" => {
                <span class="status-active">● Active</span>
            }
            "inactive" => {
                <span class="status-inactive">○ Inactive</span>
            }
            "pending" => {
                <span class="status-pending">◐ Pending</span>
            }
            _ => {
                <span class="status-unknown">? Unknown</span>
            }
        }
    </span>
}
```

#### Conditional Attributes

Use `?` for conditional attributes:

```ruitl
ruitl Input(props: InputProps) {
    <input
        type="text"
        value={props.value}
        disabled?={props.disabled}
        required?={props.required}
        placeholder={props.placeholder.as_deref().unwrap_or("")}
        class="form-input"
    />
}
```

#### Component Composition

Use `@` to invoke other components:

```ruitl
ruitl UserCard(props: UserCardProps) {
    <div class="user-card">
        <div class="user-header">
            @Avatar(
                url: props.user.avatar_url,
                name: props.user.name.clone(),
                size: "large"
            )
            <h3>{props.user.name}</h3>
        </div>

        <div class="user-actions">
            @Button(
                text: "Follow",
                variant: "primary",
                disabled: props.user.is_following
            )
            @Button(
                text: "Message",
                variant: "secondary",
                disabled: false
            )
        </div>
    </div>
}
```

### 4. Imports

Import external types and modules:

```ruitl
import "std::collections" { HashMap, Vec }
import "serde" { Serialize, Deserialize }
import "chrono" { DateTime, Utc }

component DataTable {
    props {
        data: HashMap<String, Vec<String>>,
        timestamp: DateTime<Utc>,
    }
}
```

### 5. Compilation

#### Automatic Compilation

Templates are automatically compiled during `cargo build` if you have the build script configured.

#### Manual Compilation

Use the RUITL CLI for manual compilation:

```bash
# Compile all .ruitl files in templates/ (produces sibling *_ruitl.rs next to each source)
ruitl compile --src-dir templates

# Watch mode for development
ruitl compile --src-dir templates --watch

# Create new template
ruitl template UserCard --type component --dir templates
```

### 6. Using Generated Components

After compilation, use the sibling-generated components (committed to source control, templ-style):

```rust
// src/main.rs
use ruitl::prelude::*;

// Pull in the auto-generated templates/mod.rs
#[path = "../templates/mod.rs"]
mod templates;
use templates::*;

#[tokio::main]
async fn main() -> Result<()> {
    // Create component instance
    let button = Button;

    // Create props
    let props = ButtonProps {
        text: "Click me!".to_string(),
        variant: "primary".to_string(),
        disabled: false,
    };

    // Render component
    let context = ComponentContext::new();
    let html = button.render(&props, &context)?;

    // Output HTML
    println!("{}", html.render());

    Ok(())
}
```

### 7. Project Structure

Recommended project structure:

```
my-ruitl-app/
├── Cargo.toml
├── build.rs
├── src/
│   ├── main.rs
│   ├── lib.rs
│   └── models/
│       └── user.rs
├── templates/              # RUITL sources + sibling generated *_ruitl.rs
│   ├── Button.ruitl
│   ├── Button_ruitl.rs     # generated (checked in)
│   ├── UserCard.ruitl
│   ├── UserCard_ruitl.rs   # generated (checked in)
│   ├── Layout.ruitl
│   ├── Layout_ruitl.rs     # generated (checked in)
│   └── mod.rs              # auto-generated re-exports
└── static/
    ├── style.css
    └── images/
```

### 8. Advanced Features

#### Custom Types

Define custom types for props:

```rust
// src/models/user.rs
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct User {
    pub id: u64,
    pub name: String,
    pub email: String,
    pub avatar_url: Option<String>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Post {
    pub id: u64,
    pub title: String,
    pub content: String,
    pub author: User,
    pub created_at: chrono::DateTime<chrono::Utc>,
}
```

```ruitl
// templates/PostCard.ruitl
import "crate::models" { Post, User }
import "chrono" { DateTime, Utc }

component PostCard {
    props {
        post: Post,
        show_author: bool = true,
    }
}

ruitl PostCard(props: PostCardProps) {
    <article class="post-card">
        <header class="post-header">
            <h2 class="post-title">{props.post.title}</h2>
            if props.show_author {
                <div class="post-author">
                    @UserAvatar(user: props.post.author.clone())
                    <span>by {props.post.author.name}</span>
                </div>
            }
            <time class="post-date">
                {props.post.created_at.format("%B %d, %Y").to_string()}
            </time>
        </header>

        <div class="post-content">
            {props.post.content}
        </div>
    </article>
}
```

#### Error Handling

Handle errors gracefully in templates:

```ruitl
ruitl SafeComponent(props: SafeComponentProps) {
    <div class="safe-component">
        match props.result {
            Ok(data) => {
                <div class="success">
                    <p>Success: {data}</p>
                </div>
            }
            Err(error) => {
                <div class="error">
                    <p>Error: {error.to_string()}</p>
                </div>
            }
        }
    </div>
}
```

### 9. Best Practices

1. **Keep templates focused** - One component per template file
2. **Use descriptive prop names** - Make intent clear
3. **Provide sensible defaults** - Reduce required props where possible
4. **Validate props** - Use the validation system for complex requirements
5. **Compose components** - Build complex UIs from simple, reusable parts
6. **Handle edge cases** - Always consider empty states and error conditions

### 10. IDE Setup

For the best development experience:

1. **VS Code**: Install the RUITL extension for syntax highlighting
2. **Language Server**: Configure the RUITL language server for autocompletion
3. **File associations**: Associate `.ruitl` files with the RUITL language

### 11. Debugging

#### Common Issues

1. **Parse errors**: Check syntax for missing braces, quotes, or semicolons
2. **Type errors**: Ensure prop types match Rust types exactly
3. **Import errors**: Verify import paths and exported items
4. **Missing components**: Check that referenced components are defined

#### Debug Output

Enable verbose compilation:

```bash
RUITL_DEBUG=1 cargo build
```

### 12. Migration from Runtime Library

If migrating from RUITL's runtime library approach:

1. **Extract component logic** to separate `.ruitl` files
2. **Convert `html!` macros** to template syntax
3. **Update imports** to use generated components
4. **Test incrementally** - migrate one component at a time

## Examples

See the `examples/` directory for complete working examples:

- `examples/syntax_showcase/Button.ruitl` - Syntax reference for a button (not compiled)
- `examples/syntax_showcase/UserCard.ruitl` - Full-feature syntax reference (not compiled)
- `examples/demo_templates/DemoButton.ruitl` - Compilable button used by `server_integration`
- `examples/demo_templates/DemoUserCard.ruitl` - Compilable user card used by `server_integration`
- `examples/template_compiler_demo.rs` - Full compilation workflow demo

## Resources

- [RUITL Documentation](https://docs.rs/ruitl)
- [Template Syntax Reference](./TEMPLATE_SYNTAX.md)
- [Component API Reference](./COMPONENT_API.md)
- [Examples Repository](https://github.com/sirhco/ruitl/tree/main/examples)
