# 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 %} {{title}} {% 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.