Hone logo
Hone
Problems

Go Template Rendering for Dynamic Content

This challenge focuses on creating dynamic content generation in Go using its built-in html/template package. You will learn how to define templates, provide data, and render them into strings, which is a fundamental skill for building web applications, generating reports, or sending personalized emails.

Problem Description

Your task is to implement a Go program that can render dynamic content from predefined templates. You will need to:

  1. Define a template: Create a string that represents a Go html/template. This template should accept various data types and use template actions (like variable substitution, loops, and conditional logic) to customize the output.
  2. Prepare data: Create Go data structures (structs, maps, slices) that will be passed to the template for rendering.
  3. Render the template: Use the html/template package to parse the template string and execute it with the provided data. The final rendered output should be a string.

Key Requirements:

  • The solution must use the html/template package for safe HTML rendering.
  • The template should demonstrate at least two different template actions:
    • Variable substitution ({{.FieldName}})
    • A loop ({{range .SliceField}} ... {{end}})
  • The program should accept a Go struct as data for rendering.
  • The output of the rendering process must be a string.

Expected Behavior:

The program should take a template string and a Go struct, parse the template, and then generate a new string where the placeholders in the template are replaced with values from the struct, following the logic defined in the template actions.

Edge Cases to Consider:

  • What happens if a field referenced in the template does not exist in the provided data? (The html/template package handles this gracefully by default).
  • What if a slice field is empty? (The loop should not execute).

Examples

Example 1:

Input:

Template String:

`<h1>Welcome, {{.Name}}!</h1>
<p>Your registered email is: {{.Email}}</p>
<h2>Your favorite fruits:</h2>
<ul>
{{range .FavoriteFruits}}
  <li>{{.}}</li>
{{end}}
</ul>`

Data Struct:

type UserInfo struct {
	Name           string
	Email          string
	FavoriteFruits []string
}

data := UserInfo{
	Name:           "Alice",
	Email:          "alice@example.com",
	FavoriteFruits: []string{"Apple", "Banana", "Cherry"},
}

Output:

<h1>Welcome, Alice!</h1>
<p>Your registered email is: alice@example.com</p>
<h2>Your favorite fruits:</h2>
<ul>
  <li>Apple</li>
  <li>Banana</li>
  <li>Cherry</li>
</ul>

Explanation: The template uses .Name and .Email to insert the corresponding string values. The {{range .FavoriteFruits}} iterates over the slice, printing each fruit as a list item.

Example 2:

Input:

Template String:

`<p>User ID: {{.ID}}</p>
{{if .IsAdmin}}
  <p>Role: Administrator</p>
{{else}}
  <p>Role: Regular User</p>
{{end}}`

Data Struct:

type UserProfile struct {
	ID    int
	IsAdmin bool
}

data := UserProfile{
	ID:    123,
	IsAdmin: false,
}

Output:

<p>User ID: 123</p>
  <p>Role: Regular User</p>

Explanation: This example demonstrates conditional logic ({{if}}) within the template. Based on the IsAdmin boolean, different content is rendered.

Example 3: (Edge Case - Empty Slice)

Input:

Template String:

`<h2>Your favorite snacks:</h2>
<ul>
{{range .FavoriteSnacks}}
  <li>{{.}}</li>
{{end}}
</ul>`

Data Struct:

type UserPreferences struct {
	FavoriteSnacks []string
}

data := UserPreferences{
	FavoriteSnacks: []string{}, // Empty slice
}

Output:

<h2>Your favorite snacks:</h2>
<ul>
</ul>

Explanation: Since the FavoriteSnacks slice is empty, the {{range}} loop does not execute, resulting in an empty <ul> tag.

Constraints

  • The template string will be provided as a Go string literal.
  • The data for rendering will be a Go struct.
  • The final rendered output must be a string.
  • The solution should be efficient for typical template rendering scenarios (e.g., rendering hundreds of templates with moderate data). Avoid overly complex or inefficient parsing strategies.

Notes

  • Consider how you will parse the template string and then execute it with the data. The html/template package provides functions for this.
  • Remember that html/template automatically escapes HTML to prevent XSS vulnerabilities. This is a key feature to understand.
  • You might want to create a function that encapsulates the template parsing and rendering logic.
Loading editor...
go