rshtml 0.1.0

RsHtml: A Template Engine for Seamless HTML and Rust Integration.
Documentation

RsHtml

RsHtml is a compile-time, type-safe, lightweight and flexible template engine for Rust, designed to seamlessly integrate Rust code within HTML templates. It allows developers to write dynamic templates with embedded Rust expressions and logic, making it easier to generate HTML content programmatically.

Features

  • Embeds Rust expressions and blocks directly into HTML templates using the @ prefix or HTML-like component syntax (e.g., <Component/>).
  • Supports conditional rendering (@if, @else), loops (@for), and pattern matching (@match).
  • Supports Rust code blocks (@{}), various Rust expression syntaxes (e.g., @expression, @(expression), and a broad range of other Rust syntax.
  • Includes a section system, layout system, and component system.
  • Provides helper functions (e.g., @time()).
  • Supports raw output with @raw blocks and server-side comments with @* ... *@.
  • Generates efficient Rust code for template rendering at compile time.
  • See the documentation for a full list of features.

Syntax Overview

Condition, Iteration, Pattern Matching

<h1>Welcome to RsHtml</h1>
@if self.is_logged_in {
    <p>Hello, @self.username!</p>
} else {
    <p>Please log in to continue.</p>
}

<ul>
    @for item in self.items {
        <li>@item</li>
    }
</ul>

@match self.count {
    0 => <p>this is zero</p>,
    1 => true,
    2 => self.count,
    3 => {
        <p>this is @self.count</p>
        @if self.my_var == "rshtml" {
            <p>rshtml</p>
        }
    },
    _ => <p>other</p>
}

Rust Code Blocks

@{
    let x = 42;
    let y = x * 2;
    println!("Debug: x = {}, y = {}", x, y);

    @: this is text line and x is @x 

    <text>this is text block and y is @y</text>
}

Comments

@* This is a comment and will not appear in the output *@

Sections and Layout

Section Page:
@section("title", "Home Page")

@section content {
    <p>content section</p>
}

<p>default content</p>
Layout Page:
@render("title")

@render_body   @* renders the default content *@

@if has_section("content") {
    <p>content section defined</p>
}

@render("content")

Components

@use "Component.rs.html" as Component
@use "Component.rs.html" @* take Component as name *@

<Component title="home" is_ok=true>
    <p>child content</p>
</Component>

@Component(title="home", is_ok=true) {
    <p>child content</p>
}

And much more..

Installation

To use RsHtml in your Rust project, add it as a dependency in your Cargo.toml:

[dependencies]
rshtml = "x.y.z"

Usage

  1. Define your template in an HTML file (e.g., home.rs.html).
  2. Use the RsHtml derive macro to parse the template.
  3. Render the template with render function.

main.rs

By default, #[derive(RsHtml)] infers the template file path from the struct's name. It converts StructNamePage to struct_name.rs.html. You can override this with #[rshtml(path = "...")].

use rshtml::RsHtml;

#[derive(RsHtml)]
//#[rshtml(path = "about.rs.html")] // Template can change from rshtml path param
struct HomePage { // Looks for home.rs.html
    title: String,
}

fn main() {
    let mut homepage = HomePage {
        title: "Home Page".to_string()
    };
    
    let result = homepage.render().unwrap();
    
    print!("{}", result);
}

Contributing

Contributions are welcome! Feel free to open issues or submit pull requests to improve RsHtml.