# Views Guide This guide provides detailed instructions on how to create and customize views in the Hostbasket application. ## Table of Contents 1. [Introduction to Tera Templates](#introduction-to-tera-templates) 2. [Template Structure](#template-structure) 3. [Creating a New View](#creating-a-new-view) 4. [Template Inheritance](#template-inheritance) 5. [Using Variables](#using-variables) 6. [Control Structures](#control-structures) 7. [Filters](#filters) 8. [Macros](#macros) 9. [Custom Functions](#custom-functions) 10. [Best Practices](#best-practices) ## Introduction to Tera Templates Hostbasket uses [Tera](https://tera.netlify.app/) as its template engine. Tera is inspired by Jinja2 and Django templates and provides a powerful way to create dynamic HTML pages. ## Template Structure Templates are stored in the `src/views` directory. The directory structure typically follows the application's features: ``` src/views/ ├── auth/ │ ├── login.html │ └── register.html ├── home/ │ ├── index.html │ ├── about.html │ └── contact.html ├── tickets/ │ ├── index.html │ ├── new.html │ └── show.html ├── assets/ │ ├── index.html │ ├── create.html │ └── detail.html └── base.html ``` ## Creating a New View To create a new view: 1. Create a new HTML file in the appropriate directory under `src/views` 2. Use template inheritance to extend the base template 3. Add your content within the appropriate blocks Example: ```html {% extends "base.html" %} {% block title %}My New Page{% endblock %} {% block content %}

Welcome to My New Page

This is a custom page.

{% endblock %} ``` ## Template Inheritance Tera supports template inheritance, which allows you to define a base template with common elements and extend it in child templates. ### Base Template The base template (`base.html`) typically contains the HTML structure, header, footer, and navigation menu: ```html {% block title %}Hostbasket{% endblock %} {% block head %}{% endblock %}
{% block content %}{% endblock %}
{% block scripts %}{% endblock %} ``` ### Child Template Child templates extend the base template and override specific blocks: ```html {% extends "base.html" %} {% block title %}Home{% endblock %} {% block content %}

Welcome to Hostbasket

This is the home page.

{% endblock %} {% block scripts %} {% endblock %} ``` ## Using Variables You can pass variables from your controller to the template and use them in your HTML: ### In the Controller ```rust pub async fn index(tmpl: web::Data) -> Result { let mut ctx = tera::Context::new(); ctx.insert("title", "Welcome to Hostbasket"); ctx.insert("user_name", "John Doe"); render_template(&tmpl, "home/index.html", &ctx) } ``` ### In the Template ```html

{{ title }}

Hello, {{ user_name }}!

``` ## Control Structures Tera provides various control structures for conditional rendering and iteration. ### Conditionals ```html {% if user %}

Welcome, {{ user.name }}!

{% else %}

Please log in.

{% endif %} ``` ### Loops ```html {% if items is empty %}

No items found.

{% endif %} ``` ## Filters Filters transform the values of variables: ```html

{{ user.name | upper }}

{{ user.bio | truncate(length=100) }}

{{ user.created_at | date(format="%Y-%m-%d") }}

``` ## Macros Macros are reusable template fragments: ```html {% macro input(name, value='', type='text', label='') %}
{% if label %} {% endif %}
{% endmacro %} {{ input(name="email", type="email", label="Email Address") }} ``` ## Custom Functions You can register custom functions in Rust and use them in your templates: ### In Rust ```rust fn register_tera_functions(tera: &mut Tera) { tera.register_function("format_date", format_date); } fn format_date(args: &HashMap) -> Result { // Implementation } ``` ### In the Template ```html

{{ format_date(date=user.created_at, format="%B %d, %Y") }}

``` ## Best Practices 1. **Use Template Inheritance**: Extend the base template to maintain consistency across pages. 2. **Organize Templates by Feature**: Group related templates in subdirectories. 3. **Keep Templates Simple**: Move complex logic to the controller or custom functions. 4. **Use Meaningful Variable Names**: Choose descriptive names for variables and blocks. 5. **Comment Your Templates**: Add comments to explain complex sections. 6. **Validate User Input**: Always validate and sanitize user input in the controller before passing it to the template. 7. **Use Partials for Reusable Components**: Extract common components into separate files and include them where needed. 8. **Optimize for Performance**: Minimize the use of expensive operations in templates. 9. **Test Your Templates**: Ensure that your templates render correctly with different data. 10. **Follow Accessibility Guidelines**: Make your templates accessible to all users.