Pada bab sebelumnya kita telah mengenal beberapa predefined function yang disediakan oleh Go. Kali ini kita akan belajar tentang fungsi custom, bagaimana cara membuat dan menggunakannya dalam template.
Pertama, siapkan projek baru. Buat file template view.html
, lalu isi dengan kode berikut.
<html>
<head>
<title>Learning html/template Functions</title>
</head>
<body>
{{unescape "<!-- this is comment -->"}}
{{unescape "<h2>"}}
{{avg 8 9 8 6 7 8 8}}
{{"</h2>" | unescape}}
</body>
</html>
Ada 2 hal yang perlu diperhatikan dari kode di atas. Pertama, terdapat dua buah fungsi yang dipanggil beberapa kali.
- Fungsi
unescape()
, digunakan untuk menampilkan string tanpa di-escape - Fungsi
avg()
, digunakan untuk mencari rata-rata dari angka-angka yang disisipkan sebagai parameter
Kedua fungsi tersebut adalah fungsi kustom yang akan kita buat.
Hal ke-2, terdapat 1 baris statement yang penulisannya agak unik, yaitu {{"</h2>" | unescape}}
. Statement tersebut maknanya adalah string "</h2>"
digunakan sebagai parameter dalam pemanggilan fungsi unescape
. Tanda pipe atau |
adalah penanda bahwa parameter dituliskan terlebih dahulu sebelum nama fungsi nya.
View sudah siap, sekarang saatnya pindah ke bagian back end. Isi main.go
, tentukan package sebagai main
dan import package lain yang diperlukan.
package main
import "net/http"
import "fmt"
import "html/template"
Selanjutnya beberapa fungsi akan dibuat, lalu disimpan dalam template.FuncMap
. Pembuatan fungsi dituliskan dalam bentuk key-value atau hash map. Nama fungsi sebagai key, dan body fungsi sebagai value.
var funcMap = template.FuncMap{
"unescape": func(s string) template.HTML {
return template.HTML(s)
},
"avg": func(n ...int) int {
var total = 0
for _, each := range n {
total += each
}
return total / len(n)
},
}
Tipe
template.FuncMap
sebenarnya merupakan alias darimap[string]interface{}
Dalam funcMap
di atas, dua buah fungsi disiapkan, unescape()
dan avg()
. Nantinya fungsi ini kita gunakan di view.
Setelah itu, siapkan fungsi main()
dengan isi route handler untuk /
. Di dalam handler ini, view.html
diparsing, kemudian disisipkan fungsi yang telah dibuat di atas kedalamnya.
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var tmpl = template.Must(template.New("view.html").
Funcs(funcMap).
ParseFiles("view.html"))
if err := tmpl.Execute(w, nil); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
fmt.Println("server started at localhost:9000")
http.ListenAndServe(":9000", nil)
}
Berikut merupakan penjelasan step-by-step mengenai kode panjang untuk parsing dan rendering template di atas.
- Sebuah template disipakan dengan nama
view.html
. Pembuatan instance template dilakukan melalui fungsitemplate.New()
. - Fungsi custom yang telah kita buat, diregistrasikan agar dikenali oleh template tersebut. Bisa dilihat pada pemanggilan method
Funcs()
. - Setelah itu, lewat method
ParseFiles()
, viewview.html
di-parsing. Akan dicari dalam file tersebut apakah ada template yang didefinisikan dengan namaview.html
. Karena di dalam template view tidak ada deklarasi template sama sekali ({{template "namatemplate"}}
), maka akan dicari view yang namanya adalahview.html
. Keseluruhan isiview.html
akan dianggap sebagai sebuah template dengan nama template adalah nama file itu sendiri.
Tes hasilnya lewat browser.
Pada kode di atas, pemanggilan template.New()
menghasilkan objek bertipe *template.Template
.
Pada Bab B.5. Template: Render Partial HTML Template kita telah belajar mengenai fungsi template.ParseFiles()
, yang fungsi tersebut juga mengembalikan objek bertipe *template.Template
.
Pada kode di atas, method ParseFiles()
yang dipanggil bukanlah fungsi template.ParseFiles()
yang kita telah pelajari sebelumnya. Meskipun namanya sama, kedua fungsi/method ini berbeda.
- Fungsi
template.ParseFiles()
, adalah milik packagetemplate
. Fungsi ini digunakan untuk mem-parsing semua view yang disisipkan sebagai parameter. - Method
ParseFiles()
, milik*template.Template
, digunakan untuk memparsing semua view yang disisipkan sebagai parameter, lalu diambil hanya bagian yang nama template-nya adalah sama dengan nama template yang sudah di-alokasikan menggunakantemplate.New()
. Jika template yang dicari tidak ada, maka akan mencari yang nama file-nya sama dengan nama template yang sudah ter-alokasi.
Bab selanjutnya akan membahas lebih detail mengenai penggunaan method ParseFiles()
.