Ruttle is a fast static templating engine written in Rust for generating HTML, CSS, and other text-based assets. It is designed for building static websites with minimal runtime overhead. It introduces a lightweight template language focused on:
- Variable definition and interpolation
- File composition through includes
- Conditional rendering
- Iteration
- JSON and Markdown integration
- Compile-time deduplication
Templates are evaluated at build time and compiled into plain static output.
Install using Cargo:
cargo install ruttleVerify the installation:
ruttle --versionCompile one or more template files into an output directory:
ruttle --output ./dist ./src/index.part.htmlCompile multiple files:
ruttle --output ./dist ./src/index.part.html ./src/about.part.htmlCompile and minify output:
ruttle --minify --output ./dist ./src/index.part.htmlCompile with debug logging enabled:
ruttle --debug --output ./dist ./src/index.part.html| Flag | Description |
|---|---|
-o, --output <DIR> |
Output directory |
-m, --minify |
Minify generated output |
-d, --debug |
Enable debug logging |
<INPUTS>...: One or more template files to compile. Must end with.part.htmlto prevent accidental overwriting if the input and output directories are the same.
Given the file:
<!-- src/index.part.html -->
{#define title="Hello from Ruttle"}
<h1>{#value title}</h1>Run:
ruttle --output ./dist ./src/index.part.htmlGenerated output:
<h1>Hello from Ruttle</h1>- Variable Definition and Interpolation
- File Inclusion with Props
- Conditional Rendering
- Numeric For Loops
- JSON Iteration
- Working with JSON Files
- Working with Markdown Files
- Single Inclusion
Variables can be defined using the #define directive and can be interpolated using the #value directive
{#define title="Hello, world"}
<h1>{#value title}</h1>this compiles to
<h1>Hello, world</h1>Other files can be included using the #include directives that takes in a list of key-value pairs as
properties.
If a file called button.html exists with this content
<button class="{#value color}" style="opacity:{#value opacity}">
Click me
</button>It can be included multiple times by doing this
{#include ./button.html color="red" opacity="0.8"}this compiles to
<button class="red" style="opacity:0.8">
Click me
</button>This enables reusable components with customizable inputs.
Conditional rendering can be achieved using the #if, #elseif and #else directive
{#define role="admin"}
{#if role=="admin"
<h1>Admin Panel</h1>
#elseif role=="user"
<h1>User Dashboard</h1>
#else
}this comiles to
<h1>Admin Panel</h1>The supported operations are:
- less than (
<) - greater than (
>) - less than or equal to (
>=) - greater than or equal to (
<=) - equal to (
==) - not equal to (
!=)
Values are automatically casted to integers or doubles if required
Iterate over a numeric range using the #for directive
{#for i, value in 1..5.1
<li>{#value value}</li>
}this compiles to
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>the syntax for defining a range is start..end..step where start is inclusive and end is exclusive.
Loop through arrays or objects from JSON files using the #for directive.
If ./data.json is a json file with the following content
{
"a": "Apple",
"b": "Banana"
}the object can be iterated over by
{#for key, value in ./data.json
<p>{#value key}: {#value value}</p>
}this compiles to
<p>a: Apple</p>
<p>b: Banana</p>this works with JSON Objects and JSON arrays
Values in json files can be accessed using the with directive
If ./data.json is a json file with the following content
{
"title": "My post",
"description": "Post description"
}it can be rendered using
{#with file as ./data.json
<h1>{#value file.title}</h1>
<p>{#value file.description}</p>
}this compiles to
<h1>My post</h1>
<p>Post description</p>Markdown files can be rendered as html using the with directive
If ./content.md is a markdown file with the following content
---
title: My Post
author: John
---
# Hello World
This is markdown content.it can be rendered using
{#with file as ./post.md
<article>
<h1>{#value file.title}</h1>
{#value file.content}
</article>
}this compiles to
<article>
<h1>My Post</h1>
<h1>Hello World</h1>
<p>This is markdown content.</p>
</article>The #once directive ensures content is emitted only once, even if encountered multiple times.
If ./component.html is defined like this
{#once <style>
.button {
color: red;
}
</style> }
<button class="button">Click</button>and is used like this
{#include ./component.html}
{#include ./component.html}this compiles to
<style>
.button {
color: red;
}
</style>
<button class="button">Click</button>
<button class="button">Click</button>This can be used for:
- Shared styles
- Script injection
- Preventing duplicate assets