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:

  1. What is Askama? Why use it?
  2. Setting up Askama in a Rust project
  3. Creating and rendering your first template
  4. Basic Askama syntax: expressions, statements, comments
  5. Hands-on practice and exercises
  6. 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

  1. Misconception: “Templates are only checked when I run my app.” Reality: Askama checks templates at compile time, so errors are caught early.
  2. 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 the templates/ 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 the name field.
  • 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:

  1. Create a new Rust project: cargo new askama-hello
  2. Add Askama to your Cargo.toml:
    [dependencies]
    askama = "0.16"
    
  3. Create a templates/hello.html file as shown above; askama::Template re-exports the derive macro.
  4. Implement the HelloTemplate struct and render it in main.rs.
  5. 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: u32 field to HelloTemplate.
  • Update hello.html to 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 title and a list of items (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

  1. Problem: Template file not found Cause: Wrong path or missing file Solution: Ensure the file is in templates/ and the path matches.
  2. 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 build to 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

  1. Askama provides safe, fast, and type-checked templates for Rust.
  2. Templates are checked at compile time, reducing runtime errors.
  3. Setting up and rendering a template is straightforward.

Quick Review Questions

  1. What is the main advantage of Askama over runtime template engines?
  2. How do you make a Rust struct available to a template?
  3. 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