Getting Started with Askama: Introduction, Setup & Basic Templating
Learning Objectives: By the end of this lesson, you will be able to:
- Explain what Askama is and its key benefits
- Set up Askama in a Rust project and render a simple template
- Understand and use basic Askama template syntax
1. Welcome and Introduction (5 minutes)
Icebreaker Activity
Have you ever wondered how Rust can help you catch template errors before your app even runs? Or, have you used template engines like Jinja or Handlebars and been frustrated by runtime errors?
Lesson Overview
- Duration: 60-75 minutes
- Prerequisites: Basic Rust knowledge (structs, functions, Cargo)
- Materials Needed:
- Rust toolchain (cargo, rustc)
- Code editor (VS Code, etc.)
- Internet access (for docs)
2. Learning Objectives and Session Outline (5 minutes)
What We’ll Cover Today:
- What is Askama? Why use it?
- Setting up Askama in a Rust project
- Creating and rendering your first template
- Basic Askama syntax: expressions, statements, comments
- Hands-on practice and exercises
- Common pitfalls and how to avoid them
Success Criteria:
By the end of this session, you should be able to set up Askama, create a template, and render it from Rust code.
3. Foundation Knowledge (15-20 minutes)
Core Concepts
What is Askama?
Askama is a template rendering engine for Rust, inspired by Jinja2 (Python) and the Django template language. Unlike many template engines, Askama checks your templates at compile time, catching errors before your program runs.
Real-World Analogy: Think of Askama as a spellchecker for your HTML templates that works while you write your code, not after you run it. This is like having a compiler for your templates!
Why This Matters:
- Safety: Template syntax and field-name typos are caught at compile time; data-dependent rendering and custom filters can still fail at runtime.
- Performance: Templates are compiled to Rust code, so rendering is fast.
- Type Safety: Your templates and Rust structs are checked together.
How Does Askama Differ from Other Engines?
- Compile-Time Checking: Most engines (like Jinja) only check templates at runtime.
- Integration with Rust Types: Templates are tied to Rust structs, so you get type errors if you mismatch fields.
- Performance: No template parsing at runtime.
Key Terminology
- Template: A file (usually HTML) with placeholders for dynamic data.
- Context Struct: A Rust struct that provides data to the template.
- Render: The process of filling in a template with data to produce a final string (e.g., HTML).
4. Detailed Explanation and Examples (25-30 minutes)
Understanding Askama Basics
Askama uses Rust’s procedural macros to generate code that renders your templates. You define a struct, annotate it with #[derive(Template)], and point it to a template file. When you call .render(), Askama fills in the template using the struct’s data.
Practical Applications
- Generating HTML for web apps
- Creating email templates
- Producing reports or documentation
Common Misconceptions
- Misconception: “Templates are only checked when I run my app.” Reality: Askama checks templates at compile time, so errors are caught early.
- Misconception: “I can use any field name in my template.” Reality: Only fields defined in your Rust struct are available.
5. Live Coding Demonstration (20-25 minutes)
Example 1: Basic Implementation
// main.rs
use askama::Template;
#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate {
name: String,
}
fn main() {
let template = HelloTemplate { name: "World".to_string() };
let rendered = template.render().unwrap();
println!("{}", rendered);
}
Explanation:
#[derive(Template)]: Tells Askama to generate code for this struct.#[template(path = "hello.html")]: Points to the template file in thetemplates/directory.name: String: This field will be available in the template as{{ name }}.template.render(): Renders the template with the struct’s data.
Example 2: The Template File
<!-- templates/hello.html -->
<!DOCTYPE html>
<html>
<head><title>Hello</title></head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
Key Points:
{{ name }}: Outputs the value of thenamefield.- You can use any field from your struct.
Example 3: Compile-Time Error Demonstration
<!-- templates/hello.html with a typo -->
<h1>Hello, {{ nmae }}!</h1>
What happens?
- When you build, Askama will give a compile-time error: unknown field
nmae.
Debugging Demonstration
Show common errors and how to fix them:
<!-- Incorrect: unclosed tag -->
<h1>Hello, {{ name }!
<!-- Corrected: properly closed -->
<h1>Hello, {{ name }}!</h1>
6. Hands-On Practice (30-40 minutes)
Exercise 1: Basic Practice (10 minutes)
Objective: Render a personalized greeting using Askama.
Instructions:
- Create a new Rust project:
cargo new askama-hello - Add Askama to your
Cargo.toml:[dependencies] askama = "0.16" - Create a
templates/hello.htmlfile as shown above;askama::Templatere-exports the derive macro. - Implement the
HelloTemplatestruct and render it inmain.rs. - Print the output.
Starter Code:
// main.rs
use askama::Template;
#[derive(Template)]
#[template(path = "hello.html")]
struct HelloTemplate {
name: String,
}
fn main() {
// Fill in here
}
Solution:
fn main() {
let template = HelloTemplate { name: "Alice".to_string() };
let rendered = template.render().unwrap();
println!("{}", rendered);
}
Exercise 2: Intermediate Challenge (15 minutes)
Objective: Add another field to your template and display it.
Requirements:
- Add an
age: u32field toHelloTemplate. - Update
hello.htmlto show the age. - Render and print the result.
Hints:
- Update both the struct and the template file.
- Use
{{ age }}in your template.
Exercise 3: Creative Application (15 minutes)
Objective: Create a template for a simple HTML report.
Challenge:
- Design a template that takes a
titleand a list ofitems(e.g., shopping list). - Render the list as an HTML unordered list.
Extension Ideas:
- Add a date field.
- Style the template with CSS.
7. Common Pitfalls and Troubleshooting (10 minutes)
Frequent Mistakes
- Problem: Template file not found
Cause: Wrong path or missing file
Solution: Ensure the file is in
templates/and the path matches. - Problem: Unknown field in template Cause: Typo or missing struct field Solution: Check struct and template for matching names.
Debugging Tips
- Read error messages carefully—they often point to the exact problem.
- Use
cargo buildto check for compile-time template errors. - Make small changes and rebuild often.
8. Best Practices and Professional Tips (5 minutes)
Industry Standards
- Keep templates focused on presentation, not logic.
- Use clear, descriptive field names in structs.
- Organize templates in a
templates/directory. - Leverage compile-time checks to catch errors early.
Next Steps in Your Learning Journey
- Explore Askama’s control flow and filters
- Try integrating Askama with a web framework (e.g., Axum)
- Read the Askama Book for more advanced features
9. Summary and Review (5 minutes)
Key Takeaways
- Askama provides safe, fast, and type-checked templates for Rust.
- Templates are checked at compile time, reducing runtime errors.
- Setting up and rendering a template is straightforward.
Quick Review Questions
- What is the main advantage of Askama over runtime template engines?
- How do you make a Rust struct available to a template?
- What happens if you use a field in a template that doesn’t exist in your struct?
For Instructors
Teaching Tips
- Emphasize compile-time safety and show real error messages
- Encourage students to experiment with template errors
- Allow time for hands-on setup and troubleshooting
Assessment Ideas
- Ask students to extend the template with new fields
- Review code for correct struct-template mapping
- Peer review: swap templates and structs to check for errors
Adaptation Notes
- For beginners: provide more starter code and template examples
- For advanced students: challenge them to add logic or integrate with a web framework
- Online: use live coding and screen sharing for setup steps