Data Binding in Mustache Templates

Data Binding in Mustache Templates: How to Pass Data from Spring Boot Controllers

Hey there, fellow developers! If you’re diving into Spring Boot and Mustache templates, you’ve probably wondered how to get your data from the backend to the front end smoothly. Well, you’re in luck—today I’m breaking down data binding in Mustache templates and showing you how to pass data from Spring Boot controllers like a pro. As a senior Java developer who’s been knee-deep in Spring projects for years, I’ve come to love Mustache’s simplicity, and mastering data binding is key to making it sing. In this post, I’ll share a working example, some real-world use cases, and a few tricks I’ve picked up along the way. Let’s jump in! 

Data Binding in Mustache Templates: How to Pass Data from Spring Boot Controllers
Data Binding in Mustache Templates


1. Introduction

Spring Boot paired with Mustache is a fantastic combo for building web apps with clean, logic-less templates. Mustache doesn’t let you write loops or conditionals in the template itself—that’s all handled in your Java code. So, how do you get data from your Spring Boot controllers into those templates? That’s where data binding comes in. It’s all about passing objects, lists, or even simple strings from your controller to Mustache, which then renders them into your HTML. Whether you’re displaying user profiles or dynamic lists, this guide will walk you through the process step-by-step with a practical example.

2. Usages

Data binding with Mustache is super versatile. Here are some real-world scenarios where I’ve put it to work:

  • User Profiles: Displaying a logged-in user’s name, email, or preferences pulled from a database.
  • Dynamic Lists: Rendering product catalogs, blog post feeds, or task lists that change based on backend data.
  • Form Pre-Population: Passing data to pre-fill forms—like editing a user’s details—without messy client-side hacks.
  • Personalized Content: Showing tailored messages or offers based on user behavior or roles.

It’s all about making your pages dynamic without cluttering your templates. Let’s see how to wire it up.

3. Code Example

Let’s build a simple Spring Boot app that passes a user profile and a list of recent activities to a Mustache template. Think of it as a mini dashboard.

Project Setup
  • Spring Boot version: 3.2.x
  • Dependency: spring-boot-starter-mustache
pom.xml

    org.springframework.boot
    spring-boot-starter-mustache

Application Properties (application.yml)
spring:
  mustache:
    suffix: .mustache
Model (UserProfile.java)
public class UserProfile {
    private String name;
    private String email;
    private List<String> activities;

    public UserProfile(String name, String email, List<String> activities) {
        this.name = name;
        this.email = email;
        this.activities = activities;
    }

    // Getters and setters
    public String getName() { return name; }
    public String getEmail() { return email; }
    public List<String> getActivities() { return activities; }
    public void setName(String name) { this.name = name; }
    public void setEmail(String email) { this.email = email; }
    public void setActivities(List<String> activities) { this.activities = activities; }
}
Controller (ProfileController.java)
@Controller
public class ProfileController {

    @GetMapping("/profile")
    public String getProfile(Model model) {
        List<String> activities = Arrays.asList(
            "Logged in at 9:00 AM",
            "Updated profile picture",
            "Completed a task"
        );
        UserProfile profile = new UserProfile("Jane Doe", "jane@example.com", activities);
        
        model.addAttribute("profile", profile);
        model.addAttribute("pageTitle", "User Dashboard");
        return "profile";
    }
}
Mustache Template (src/main/resources/templates/profile.mustache)


    {{pageTitle}}
    


    

{{pageTitle}}

Welcome, {{profile.name}}!

Email: {{profile.email}}

Recent Activities

    {{#profile.activities}}
  • {{.}}
  • {{/profile.activities}} {{^profile.activities}}
  • No recent activities.
  • {{/profile.activities}}
Main Application (DemoApplication.java)
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Run the app and visit http://localhost:8080/profile. You’ll see a user dashboard with bound data from the controller!

4. Explanation

Let’s unpack how this works:

  • Dependency: The spring-boot-starter-mustache dependency sets up Mustache, expecting templates in src/main/resources/templates.
  • Controller: The ProfileController creates a UserProfile object with a name, email, and activity list. It uses model.addAttribute() to bind this data (and a page title) to the template.
  • Template: Mustache binds the data with placeholders:
    • {{pageTitle}} grabs the string directly.
    • {{profile.name}} and {{profile.email}} access object properties.
    • {{#profile.activities}} loops over the list, with {{.}} rendering each item. The {{^profile.activities}} block handles the empty case.
  • Data Flow: Spring Boot passes the model to Mustache, which compiles it into HTML. No logic in the template—just pure data binding.

This keeps your Java code in charge and your template focused on display.

5. Best Practices

Here’s what I’ve learned to keep data binding with Mustache smooth:

  • Use Meaningful Names: Name your model attributes clearly (e.g., profile vs. p) so your templates read like English.
  • Handle Nulls: Always include fallback blocks (like {{^profile.activities}}) to avoid blank spots if data’s missing.
  • Keep Data Lean: Pass only what the template needs—don’t overload the model with unused objects.
  • Test Binding: Use unit tests with MockMvc to verify your controller passes the right data. I’ve caught silly mistakes this way!
  • SEO Optimize: Add meta tags and keywords (e.g., “Spring Boot Mustache data binding”) to your templates for better search rankings.

6. Conclusion

And there you have it—your guide to data binding in Mustache templates with Spring Boot! It’s a straightforward, powerful way to connect your controllers to your views without cluttering things up. The profile example is a solid starting point—tweak it for your own dashboards, lists, or forms. I love how Mustache keeps the logic where it belongs (in Java) and lets me focus on crafting great user experiences. Tried this out yet? Got a cool data-binding trick? Drop a comment—I’d love to hear from you! Happy coding, and catch you in the next one!

Post a Comment

Previous Post Next Post