# Rustelo Template System
A powerful localized template system for Rustelo using Tera templates and TOML configuration files.
## Overview
The Rustelo template system allows you to create dynamic pages using:
- **Tera Templates**: Flexible HTML templates with variables, filters, and logic
- **TOML Configuration**: `.tpl.toml` files that define template data and settings
- **Localization**: Multi-language support with language-prefixed configuration files
- **URL Routing**: Clean URLs like `/page:content-name` that map to template configurations
## How It Works
### 1. Template Files
Templates are HTML files with Tera syntax stored in the `templates/` directory:
```html
{{title}}
{{title}}
By {{author}} on {{published_date}}
{{content | markdown | safe}}
```
### 2. Configuration Files
Configuration files are TOML files that specify which template to use and provide data:
```toml
# content/docs/en_my-blog-post.tpl.toml
template_name = "blog-post"
[values]
title = "My First Blog Post"
author = "John Doe"
published_date = "2024-01-15"
content = """
# Hello World
This is my first blog post using Rustelo's template system!
## Features
- Easy to use
- Localized content
- Flexible templating
"""
```
### 3. URL Mapping
The system maps URLs to configuration files using language prefixes:
- URL: `/page:my-blog-post?lang=en`
- Maps to: `content/docs/en_my-blog-post.tpl.toml`
- Uses template: `templates/blog-post.html`
## Directory Structure
```
rustelo/
├── templates/ # Tera template files
│ ├── blog-post.html
│ ├── page.html
│ └── layout.html
├── content/
│ └── docs/ # Template configuration files
│ ├── en_getting-started.tpl.toml
│ ├── es_getting-started.tpl.toml
│ ├── en_about.tpl.toml
│ └── fr_about.tpl.toml
└── server/src/template/ # Template system code
├── mod.rs
├── config.rs
├── engine.rs
├── loader.rs
├── service.rs
└── routes.rs
```
## Quick Start
### 1. Create a Template
Create `templates/my-page.html`:
```html
{{title}}
{{title}}
{{description}}
{% if featured_image %}
{% endif %}
{{content | markdown | safe}}
{% if tags %}
{% for tag in tags %}
{{tag}}
{% endfor %}
{% endif %}
```
### 2. Create Configuration Files
Create `content/docs/en_my-page.tpl.toml`:
```toml
template_name = "my-page"
[values]
title = "Welcome to My Page"
description = "This is a sample page created with Rustelo templates"
featured_image = "/images/welcome.jpg"
content = """
# Welcome!
This page demonstrates the Rustelo template system.
## Features
- **Localization**: Multiple languages supported
- **Flexible**: Use any template with any data
- **Fast**: Cached rendering for performance
"""
tags = ["welcome", "demo", "rustelo"]
[metadata]
category = "sample"
author = "Your Name"
created_date = "2024-01-15"
```
Create `content/docs/es_my-page.tpl.toml`:
```toml
template_name = "my-page"
[values]
title = "Bienvenido a Mi Página"
description = "Esta es una página de ejemplo creada con plantillas Rustelo"
featured_image = "/images/welcome.jpg"
content = """
# ¡Bienvenido!
Esta página demuestra el sistema de plantillas de Rustelo.
## Características
- **Localización**: Múltiples idiomas soportados
- **Flexible**: Usa cualquier plantilla con cualquier dato
- **Rápido**: Renderizado en caché para rendimiento
"""
tags = ["bienvenida", "demo", "rustelo"]
[metadata]
category = "muestra"
author = "Tu Nombre"
created_date = "2024-01-15"
```
### 3. Access Your Page
- English: `http://localhost:3030/page:my-page?lang=en`
- Spanish: `http://localhost:3030/page:my-page?lang=es`
- Default: `http://localhost:3030/page:my-page` (uses default language)
## Configuration Reference
### Template Configuration Format
```toml
# Required: Template file to use (without .html extension)
template_name = "blog-post"
# Required: Data to pass to the template
[values]
title = "Page Title"
content = "Page content in markdown"
author = "Author Name"
tags = ["tag1", "tag2"]
enable_comments = true
custom_data = { key = "value" }
# Optional: Metadata not passed to template
[metadata]
category = "blog"
seo_title = "Custom SEO Title"
seo_description = "Custom SEO Description"
```
### Built-in Template Variables
The system automatically provides these variables to all templates:
- `template_name`: The name of the template being used
- `source_path`: Path to the configuration file
- `lang`: Current language code
- `metadata`: The metadata section from the configuration
### Built-in Filters
- `markdown`: Convert markdown to HTML
- `date_format`: Format dates
- `slug`: Convert text to URL-friendly slug
- `excerpt`: Extract excerpt from text
- `safe`: Mark content as safe HTML
Example usage:
```html
{{content | markdown | safe}}
{{published_date | date_format(format="%B %d, %Y")}}
{{title | slug}}
{{description | excerpt(length=150)}}
```
## Language Support
### Language Fallback Chain
When requesting a page, the system follows this fallback chain:
1. **Requested language**: `{lang}_{content-name}.tpl.toml`
2. **Default language**: `{default_lang}_{content-name}.tpl.toml`
3. **No prefix**: `{content-name}.tpl.toml`
### Configuration
```rust
let template_service = TemplateService::new("templates", "content/docs")?
.with_languages(vec!["en".to_string(), "es".to_string(), "fr".to_string()])
.with_default_language("en");
```
## API Endpoints
### Template Page Endpoints
- `GET /page/:content_name?lang=:lang` - Serve template page as HTML
- `GET /api/template/:content_name?lang=:lang` - Get template page as JSON
### Management Endpoints
- `GET /api/template/list/:lang` - List available content for language
- `GET /api/template/languages` - Get available languages
- `GET /api/template/stats` - Get template service statistics
- `POST /api/template/cache/clear` - Clear template cache
- `POST /api/template/reload` - Reload templates from disk
- `GET /api/template/exists/:content_name?lang=:lang` - Check if template exists
- `GET /api/template/config/:content_name?lang=:lang` - Get template configuration
- `GET /api/template/health` - Template service health check
## Advanced Features
### Custom Filters
```rust
// Add custom filter to template service
template_service.add_filter("reverse", |value: &Value, _: &HashMap| {
let text = value.as_str().unwrap_or("");
Ok(Value::String(text.chars().rev().collect()))
})?;
```
### Custom Functions
```rust
// Add custom function to template service
template_service.add_function("current_year", |_: &HashMap| {
Ok(Value::Number(2024.into()))
})?;
```
### Template Inheritance
```html
{% block title %}Default Title{% endblock %}
{% block content %}{% endblock %}
```
```html
{% extends "base.html" %}
{% block title %}{{title}} - {{site_name}}{% endblock %}
{% block content %}
{{title}}
{{content | markdown | safe}}
{% endblock %}
```
## Performance Tips
1. **Enable Caching**: Keep caching enabled in production
2. **Preload Templates**: Use `preload_language()` to cache templates at startup
3. **Template Compilation**: Templates are compiled once and cached
4. **Static Assets**: Use proper static file serving for images and CSS
## Development Workflow
1. Create template HTML files in `templates/`
2. Create configuration files in `content/docs/`
3. Test with `?reload=true` to reload templates during development
4. Use the API endpoints to debug and inspect configurations
5. Check template service health with `/api/template/health`
## Examples
See the included example files:
- `templates/blog-post.html` - Blog post template
- `templates/page.html` - General page template
- `content/docs/en_getting-started.tpl.toml` - Getting started page
- `content/docs/es_getting-started.tpl.toml` - Spanish getting started page
- `content/docs/en_about.tpl.toml` - About page
## Integration with Rustelo
The template system integrates seamlessly with Rustelo's existing features:
- **Authentication**: Use auth middleware to protect template routes
- **Database**: Store template metadata in database if needed
- **Localization**: Works with Rustelo's existing i18n system
- **Caching**: Leverages Rustelo's caching infrastructure
## Troubleshooting
### Template Not Found
- Check file naming: `{lang}_{content-name}.tpl.toml`
- Verify template file exists in `templates/`
- Check template_name in configuration matches template filename
### Rendering Errors
- Use `/api/template/config/:content_name` to inspect configuration
- Check template syntax with Tera documentation
- Verify all required variables are provided in `[values]`
### Performance Issues
- Enable caching in production
- Use template preloading
- Monitor with `/api/template/stats`
For more help, check the logs or use the health check endpoint.