Skip to main content

Echo Template Variables

Introduction

When building web applications with the Echo framework in Go, templates are a powerful way to generate dynamic HTML content. One of the most important aspects of working with templates is the ability to use variables - placeholders that will be replaced with actual data when the template is rendered.

In this guide, we'll explore how to define, pass, and use variables in Echo templates, allowing you to create dynamic and data-driven web pages.

Understanding Template Variables

Template variables are placeholders within your HTML templates that get replaced with actual values when the template is rendered. They allow you to:

  • Display dynamic content from your Go code
  • Reuse template components with different data
  • Create conditional elements based on data values
  • Loop through collections of data

Basic Variable Syntax

In Echo templates (which typically use Go's standard html/template package), variables are denoted with double curly braces:

html
<h1>Hello, {{.Name}}!</h1>

The dot (.) represents the data passed to the template, and Name is a field or property we're accessing from that data.

Passing Variables to Templates

To pass variables to a template in Echo, you use the c.Render() method with a map or struct containing your data:

go
func HomeHandler(c echo.Context) error {
// Create data to pass to template
data := map[string]interface{}{
"Name": "John",
"Age": 30,
"Items": []string{
"Apple",
"Banana",
"Cherry",
},
}

// Render template with data
return c.Render(http.StatusOK, "home.html", data)
}

Accessing Variables in Templates

Simple Variable Access

To display a variable in your template:

html
<p>Name: {{.Name}}</p>
<p>Age: {{.Age}}</p>

Output:

Name: John
Age: 30

Accessing Nested Structures

For nested data structures like structs within structs:

go
// In your Go handler
data := map[string]interface{}{
"User": struct {
Name string
Profile struct {
Bio string
Website string
}
}{
Name: "Alice",
Profile: struct {
Bio string
Website string
}{
Bio: "Software Developer",
Website: "alice.dev",
},
},
}

In your template:

html
<h1>{{.User.Name}}</h1>
<p>Bio: {{.User.Profile.Bio}}</p>
<p>Website: {{.User.Profile.Website}}</p>

Output:

Alice
Bio: Software Developer
Website: alice.dev

Iterating Through Collections

For slices and arrays, use the range keyword:

html
<ul>
{{range .Items}}
<li>{{.}}</li>
{{end}}
</ul>

Output:

• Apple
• Banana
• Cherry

For a slice of structs:

go
// In your Go handler
type Product struct {
Name string
Price float64
}

data := map[string]interface{}{
"Products": []Product{
{Name: "Laptop", Price: 999.99},
{Name: "Phone", Price: 599.99},
{Name: "Headphones", Price: 99.99},
},
}

In your template:

html
<table>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
{{range .Products}}
<tr>
<td>{{.Name}}</td>
<td>${{.Price}}</td>
</tr>
{{end}}
</table>

Conditional Rendering

You can use if, else if, and else conditions to conditionally render content:

html
{{if .IsLoggedIn}}
<p>Welcome back, {{.Username}}!</p>
{{else}}
<p>Please log in to continue.</p>
{{end}}

Checking numerical values:

html
{{if eq .Stock 0}}
<span class="badge bg-danger">Out of stock</span>
{{else if lt .Stock 5}}
<span class="badge bg-warning">Low stock: {{.Stock}} remaining</span>
{{else}}
<span class="badge bg-success">In stock: {{.Stock}} available</span>
{{end}}

Using Template Functions with Variables

Go templates provide built-in functions to transform variables:

html
<!-- Convert to uppercase -->
<p>{{.Name | upper}}</p>

<!-- Format a date -->
<p>Posted on: {{.CreatedAt | formatDate}}</p>

<!-- Truncate long text -->
<p>{{.Description | truncate 100}}</p>

To use custom functions like formatDate or truncate, you need to register them with your template engine.

Variable Scope in Templates

Global vs Block Scope

Variables declared in a template are typically available throughout the template. However, when using blocks or control structures, you might need to save variables locally:

html
{{$username := .User.Name}}

{{range .Items}}
<!-- Here, "." refers to the current item, not the root data -->
<p>{{$username}} added {{.ProductName}} to cart</p>
{{end}}

Defining Local Variables

You can create local variables in templates using the $ prefix:

html
{{$total := 0}}
{{range .CartItems}}
{{$total = add $total .Price}}
<p>{{.Name}}: ${{.Price}}</p>
{{end}}
<p>Total: ${{$total}}</p>

Real-world Example: User Dashboard

Here's a practical example of using variables in a user dashboard template:

go
// Handler function
func DashboardHandler(c echo.Context) error {
// Get user ID from session, load data from database, etc.
user := getUserFromSession(c)
recentOrders := getRecentOrders(user.ID)
recommendations := getRecommendedProducts(user.ID)

data := map[string]interface{}{
"User": user,
"RecentOrders": recentOrders,
"Recommendations": recommendations,
"Stats": map[string]int{
"TotalOrders": user.TotalOrders,
"PendingDeliveries": user.PendingDeliveries,
},
}

return c.Render(http.StatusOK, "dashboard.html", data)
}

Dashboard template:

html
<div class="dashboard">
<header>
<h1>Welcome back, {{.User.Name}}!</h1>
<p>Member since {{.User.JoinDate | formatDate "Jan 2006"}}</p>
</header>

<div class="stats">
<div class="stat-card">
<h3>Total Orders</h3>
<p class="stat-number">{{.Stats.TotalOrders}}</p>
</div>

<div class="stat-card">
<h3>Pending Deliveries</h3>
<p class="stat-number">{{.Stats.PendingDeliveries}}</p>
</div>
</div>

<h2>Recent Orders</h2>
{{if .RecentOrders}}
<table class="orders-table">
<tr>
<th>Order ID</th>
<th>Date</th>
<th>Amount</th>
<th>Status</th>
</tr>
{{range .RecentOrders}}
<tr>
<td>#{{.ID}}</td>
<td>{{.Date | formatDate "Jan 2, 2006"}}</td>
<td>${{.Amount | printf "%.2f"}}</td>
<td>
{{if eq .Status "delivered"}}
<span class="status delivered">Delivered</span>
{{else if eq .Status "shipped"}}
<span class="status shipped">Shipped</span>
{{else}}
<span class="status processing">Processing</span>
{{end}}
</td>
</tr>
{{end}}
</table>
{{else}}
<p>You haven't placed any orders yet.</p>
{{end}}

<h2>Recommended For You</h2>
<div class="product-grid">
{{range .Recommendations}}
<div class="product-card">
<img src="{{.ImageURL}}" alt="{{.Name}}">
<h3>{{.Name}}</h3>
<p>${{.Price | printf "%.2f"}}</p>
<button>Add to Cart</button>
</div>
{{end}}
</div>
</div>

Best Practices for Template Variables

  1. Use Descriptive Names: Choose meaningful names for your variables that indicate their purpose and content.

  2. Minimize Logic in Templates: While templates can handle some logic, keep complex operations in your Go code.

  3. Default Values: Provide fallbacks for variables that might be empty.

    html
    <p>{{.Description | default "No description available"}}</p>
  4. Escape HTML When Needed: By default, Go templates automatically escape HTML content to prevent XSS attacks. Use the html function if you need to explicitly escape content, or safeHTML if you want to render raw HTML (be careful!).

  5. Structure Data Logically: Organize your data structures in a way that makes template access intuitive and readable.

Summary

Echo template variables provide a powerful way to create dynamic web pages by passing data from your Go handlers to your HTML templates. By mastering template variables, you can:

  • Display dynamic data in your HTML pages
  • Create conditional elements and loops
  • Format and transform data as needed
  • Build reusable template components

Understanding how to effectively use template variables is essential for developing modern web applications with Echo.

Additional Resources and Exercises

Resources

Exercises

  1. Basic Profile Page: Create a template that displays user profile information including name, bio, and contact information.

  2. Product Listing: Build a template that displays a list of products with different badges based on availability.

  3. Blog Post Template: Design a template for blog posts that formats dates, displays author information, and renders content with proper formatting.

  4. Comment System: Create a template that displays nested comments with proper indentation and user information.

  5. Advanced Dashboard: Extend the dashboard example with additional sections like account settings, activity history, and personalized recommendations.

By working through these exercises, you'll gain practical experience with template variables and improve your skills in building dynamic web interfaces with Echo.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)