Templates
Go menyediakan package text/template dan html/template untuk menghasilkan output terformat. Package html/template khususnya aman untuk konten HTML.
Contoh Masalah
Bagaimana cara:
- Membuat dan menggunakan template
- Menggunakan fungsi template
- Nested templates
- Safe HTML output
Penyelesaian
package main
import (
"fmt"
"html/template"
"os"
"strings"
"time"
)
// 1. Data structures
type User struct {
Name string
Age int
Email string
CreatedAt time.Time
}
type Post struct {
Title string
Content string
Author User
Tags []string
Comments []Comment
}
type Comment struct {
Author string
Content string
Date time.Time
}
// 2. Custom template functions
var funcMap = template.FuncMap{
"upper": strings.ToUpper,
"formatDate": func(t time.Time) string {
return t.Format("02 Jan 2006")
},
"inc": func(n int) int {
return n + 1
},
"join": strings.Join,
}
// Template files
const (
baseTemplate = `
<!DOCTYPE html>
<html>
<head>
<title>{{template "title" .}}</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.post { margin-bottom: 20px; }
.comments { margin-left: 20px; }
</style>
</head>
<body>
{{template "content" .}}
{{template "footer" .}}
</body>
</html>
`
postTemplate = `
{{define "title"}}{{.Title}}{{end}}
{{define "content"}}
<div class="post">
<h1>{{.Title}}</h1>
<p>{{.Content}}</p>
<h3>Author</h3>
{{template "user" .Author}}
<h3>Tags</h3>
<p>{{join .Tags ", " | upper}}</p>
<h3>Comments</h3>
<div class="comments">
{{range $i, $comment := .Comments}}
{{template "comment" $comment}}
{{else}}
<p>No comments yet.</p>
{{end}}
</div>
</div>
{{end}}
{{define "footer"}}
<footer>
<p>© {{.Author.Name}} - {{formatDate .Author.CreatedAt}}</p>
</footer>
{{end}}
`
userTemplate = `
{{define "user"}}
<div class="user">
<p>Name: {{.Name}}</p>
<p>Age: {{.Age}}</p>
<p>Email: {{.Email}}</p>
<p>Member since: {{formatDate .CreatedAt}}</p>
</div>
{{end}}
`
commentTemplate = `
{{define "comment"}}
<div class="comment">
<p><strong>{{.Author}}</strong> - {{formatDate .Date}}</p>
<p>{{.Content}}</p>
</div>
{{end}}
`
)
func main() {
// Create template
tmpl := template.New("base").Funcs(funcMap)
// Parse all templates
template.Must(tmpl.Parse(baseTemplate))
template.Must(tmpl.Parse(postTemplate))
template.Must(tmpl.Parse(userTemplate))
template.Must(tmpl.Parse(commentTemplate))
// Sample data
post := Post{
Title: "Belajar Go Templates",
Content: "Go menyediakan sistem template yang powerful...",
Author: User{
Name: "John Doe",
Age: 30,
Email: "john@example.com",
CreatedAt: time.Now().Add(-24 * time.Hour * 365),
},
Tags: []string{"go", "programming", "template"},
Comments: []Comment{
{
Author: "Alice",
Content: "Artikel yang sangat membantu!",
Date: time.Now().Add(-24 * time.Hour),
},
{
Author: "Bob",
Content: "Saya suka penjelasannya.",
Date: time.Now().Add(-12 * time.Hour),
},
},
}
// Execute template
err := tmpl.Execute(os.Stdout, post)
if err != nil {
fmt.Printf("Error executing template: %v\n", err)
}
}
File Template
Simpan template dalam file terpisah:
templates/base.html:
<!DOCTYPE html>
<html>
<head>
<title>{{template "title" .}}</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.post { margin-bottom: 20px; }
.comments { margin-left: 20px; }
</style>
</head>
<body>
{{template "content" .}}
{{template "footer" .}}
</body>
</html>
templates/post.html:
{{define "title"}}{{.Title}}{{end}}
{{define "content"}}
<div class="post">
<h1>{{.Title}}</h1>
<p>{{.Content}}</p>
<h3>Author</h3>
{{template "user" .Author}}
<h3>Tags</h3>
<p>{{join .Tags ", " | upper}}</p>
<h3>Comments</h3>
<div class="comments">
{{range $i, $comment := .Comments}}
{{template "comment" $comment}}
{{else}}
<p>No comments yet.</p>
{{end}}
</div>
</div>
{{end}}
{{define "footer"}}
<footer>
<p>© {{.Author.Name}} - {{formatDate .Author.CreatedAt}}</p>
</footer>
{{end}}
Cara menggunakan file template:
// Load templates from files
tmpl := template.New("base").Funcs(funcMap)
template.Must(tmpl.ParseFiles(
"templates/base.html",
"templates/post.html",
"templates/user.html",
"templates/comment.html",
))
Penjelasan Kode
Basic Template
- Variable substitution
- Control structures
- Nested templates
Template Functions
- Built-in functions
- Custom functions
- Pipelines
Security
- HTML escaping
- Safe content
- XSS prevention
Output
<!DOCTYPE html>
<html>
<head>
<title>Belajar Go Templates</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.post { margin-bottom: 20px; }
.comments { margin-left: 20px; }
</style>
</head>
<body>
<div class="post">
<h1>Belajar Go Templates</h1>
<p>Go menyediakan sistem template yang powerful...</p>
<h3>Author</h3>
<div class="user">
<p>Name: John Doe</p>
<p>Age: 30</p>
<p>Email: john@example.com</p>
<p>Member since: 21 Jan 2023</p>
</div>
<h3>Tags</h3>
<p>GO, PROGRAMMING, TEMPLATE</p>
<h3>Comments</h3>
<div class="comments">
<div class="comment">
<p><strong>Alice</strong> - 20 Jan 2024</p>
<p>Artikel yang sangat membantu!</p>
</div>
<div class="comment">
<p><strong>Bob</strong> - 20 Jan 2024</p>
<p>Saya suka penjelasannya.</p>
</div>
</div>
</div>
<footer>
<p>© John Doe - 21 Jan 2023</p>
</footer>
</body>
</html>
Tips
- Gunakan html/template untuk web
- Pisahkan template dalam file
- Manfaatkan template functions
- Handle error dengan baik
- Perhatikan keamanan output