2013-07-24 41 views
18

Sử dụng html/template Tôi đang cố gắng sử dụng một trong các chức năng của riêng mình bên trong mẫu. Rất tiếc, tôi không thể sử dụng tính năng bản đồ chức năng của các mẫu của go. Tất cả tôi nhận được là các lỗi sau:Mẫu và chức năng tùy chỉnh; hoảng loạn: chức năng không được xác định

% go run test.go 
panic: template: tmpl.html:5: function "humanSize" not defined 
[...] 

Các testcase giảm trông như sau (test.go):

package main 

import (
    "html/template" 
    "io/ioutil" 
    "net/http" 
    "strconv" 
) 

var funcMap = template.FuncMap{ 
    "humanSize": humanSize, 
} 
var tmplGet = template.Must(template.ParseFiles("tmpl.html")).Funcs(funcMap) 

func humanSize(s int64) string { 
    return strconv.FormatInt(s/int64(1000), 10) + " KB" 
} 

func getPageHandler(w http.ResponseWriter, r *http.Request) { 
    files, _ := ioutil.ReadDir(".") 
    if err := tmplGet.Execute(w, files); err != nil { 
     http.Error(w, err.Error(), http.StatusInternalServerError) 
    } 
} 

func main() { 
    http.HandleFunc("/", getPageHandler) 
    http.ListenAndServe(":8080", nil) 
} 

Và tôi có các mẫu sau đây đơn giản (tmpl.html):

<html><body> 
    {{range .}} 
    <div> 
     <span>{{.Name}}</span> 
     <span>{{humanSize .Size}}</span> 
    </div> 
    {{end}} 
</body></html> 

Điều này là 1.1.1.

Trả lời

30

IIRC, bản đồ hàm mẫu phải được xác định bởi .Funcs trước khi phân tích mẫu. Mã bên dưới dường như hoạt động.

package main 

import (
     "html/template" 
     "io/ioutil" 
     "net/http" 
     "strconv" 
) 

var funcMap = template.FuncMap{ 
     "humanSize": humanSize, 
} 

const tmpl = ` 
<html><body> 
    {{range .}} 
    <div> 
     <span>{{.Name}}</span> 
     <span>{{humanSize .Size}}</span> 
    </div> 
    {{end}} 
</body></html>` 

var tmplGet = template.Must(template.New("").Funcs(funcMap).Parse(tmpl)) 

func humanSize(s int64) string { 
     return strconv.FormatInt(s/int64(1000), 10) + " KB" 
} 

func getPageHandler(w http.ResponseWriter, r *http.Request) { 
     files, err := ioutil.ReadDir(".") 
     if err != nil { 
       http.Error(w, err.Error(), http.StatusInternalServerError) 
       return 
     } 

     if err := tmplGet.Execute(w, files); err != nil { 
       http.Error(w, err.Error(), http.StatusInternalServerError) 
     } 
} 

func main() { 
     http.HandleFunc("/", getPageHandler) 
     http.ListenAndServe(":8080", nil) 
} 
+22

Cảm ơn bạn. Rõ ràng là bạn cần thêm bản đồ hàm trước khi phân tích mẫu; Tôi không thể tìm thấy điều đó trong tài liệu. Tôi đã kết thúc với 'var tmplGet = template.Must (template.New (" base.html "). Funcs (funcMap) .ParseFiles (" tmpl/base.html "," tmpl/get.html "))', bởi vì Tôi sử dụng các mẫu lồng nhau. Ở đây một dấu khác là 'New()' cần có cùng tên cơ sở như là mẫu "cấp cao nhất". –

0

Giải pháp là phải có tên giống nhau trong chức năng mới() và Parse Files() một gợi ý bởi @ user321277

var tmplGet = template.Must(template.New("base.html").Funcs(funcMap).Parse‌​Files("tmpl/base.htm‌​l", "tmpl/get.html")) 
Các vấn đề liên quan