doudoulb1234 2017-04-07 17:47
浏览 443
已采纳

可以自称的Golang模板FuncMap

I am trying to achieve a function to add to FuncMaps in a base template, and this function should be used to render re-useable view components

For instance:

func (v *Item) RenderComponent(componentPath string, vars ...interface{}) template.HTML {
    p := path.Join(v.folder, "components", componentPath)

    // Get the pieces of the component path.
    componentPathPieces := strings.Split(p, "/")

    // Get the last item in the pieces (this should be the file name).
    componentFileName := componentPathPieces[len(componentPathPieces)-1]

    // Make the new template using component file name and add FuncMap functions.
    t := template.New(componentFileName).Funcs(v.funcMap)

    // Determine if there is an error in the template syntax.
    t, err := template.ParseFiles(p + "." + v.extension)
    if err != nil {
        panic(err)
    }

    // Add variables to the component and write to a buffer.
    b := new(bytes.Buffer)
    if err = t.Execute(b, vars); err != nil {
        panic(err)
    }

    // Return the contents of the template buffer as a string of HTML.
    return template.HTML(b.String())
}

This code works just fine for a component that doesn't render another component. For example, I can write {{component "buttons/default-button" "some url goes here"}} and it will render the component at components/button/default-button.tmpl just fine.

However, if I include another component within that default-button component, such as {{component "icons/check-icon"}}, I will get a large error (too big to paste here). But here is one of the error messages:

template: default-button.tmpl:4: function "component" not defined

As you can see, the error is thrown from the component file that is trying to call another component. I believe that happens because the viewFunc is either not being properly added, or is being recursively called in some way.

  • 写回答

1条回答 默认 最新

  • dongshi9526 2017-04-07 18:52
    关注

    Oops, looked like I had a typo.

    Had to change this:

    // Make the new template using component file name and add FuncMap functions.
    t := template.New(componentFileName).Funcs(v.funcMap)
    
    // Determine if there is an error in the template syntax.
    t, err := template.ParseFiles(p + "." + v.extension)
    

    ...to this:

    // Make the new template using component file name and add FuncMap functions.
    t := template.New(componentFileName + "." + v.extension).Funcs(v.funcMap) // <---- 'componentFileName' to 'componentFileName + "." + v.extension'
    
    // Determine if there is an error in the template syntax.
    t, err := t.ParseFiles(p + "." + v.extension) // <---- 'template' to 't'
    

    I was referencing the template package instead of the t template that I created. I also passed in the wrong name for template.New, since that expects a full fill such as index.tmpl, instead of just index.

    Now everything works as expected! Can call component from another component.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计
  • ¥15 路易威登官网 里边的参数逆向
  • ¥15 Arduino无法同时连接多个hx711模块,如何解决?
  • ¥50 需求一个up主付费课程