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:
<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:
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:
<p>Name: {{.Name}}</p>
<p>Age: {{.Age}}</p>
Output:
Name: John
Age: 30
Accessing Nested Structures
For nested data structures like structs within structs:
// 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:
<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:
<ul>
{{range .Items}}
<li>{{.}}</li>
{{end}}
</ul>
Output:
• Apple
• Banana
• Cherry
For a slice of structs:
// 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:
<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:
{{if .IsLoggedIn}}
<p>Welcome back, {{.Username}}!</p>
{{else}}
<p>Please log in to continue.</p>
{{end}}
Checking numerical values:
{{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:
<!-- 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:
{{$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:
{{$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:
// 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:
<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
-
Use Descriptive Names: Choose meaningful names for your variables that indicate their purpose and content.
-
Minimize Logic in Templates: While templates can handle some logic, keep complex operations in your Go code.
-
Default Values: Provide fallbacks for variables that might be empty.
html<p>{{.Description | default "No description available"}}</p>
-
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, orsafeHTML
if you want to render raw HTML (be careful!). -
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
-
Basic Profile Page: Create a template that displays user profile information including name, bio, and contact information.
-
Product Listing: Build a template that displays a list of products with different badges based on availability.
-
Blog Post Template: Design a template for blog posts that formats dates, displays author information, and renders content with proper formatting.
-
Comment System: Create a template that displays nested comments with proper indentation and user information.
-
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! :)