du4373 2013-08-16 14:51
浏览 46
已采纳

调用带有多个管道参数的模板

In a Go template, sometimes the way to pass the right data to the right template feels awkward to me. Calling a template with a pipeline parameter looks like calling a function with only one parameter.

Let's say I have a site for Gophers about Gophers. It has a home page main template, and a utility template to print a list of Gophers.

http://play.golang.org/p/Jivy_WPh16

Output :

*The great GopherBook*    (logged in as Dewey)

    [Most popular]  
        >> Huey
        >> Dewey
        >> Louie

    [Most active]   
        >> Huey
        >> Louie

    [Most recent]   
        >> Louie

Now I want to add a bit of context in the subtemplate : format the name "Dewey" differently inside the list because it's the name of the currently logged user. But I can't pass the name directly because there is only one possible "dot" argument pipeline! What can I do?

  • Obviously I can copy-paste the subtemplate code into the main template (I don't want to because it drops all the interest of having a subtemplate).
  • Or I can juggle with some kind of global variables with accessors (I don't want to either).
  • Or I can create a new specific struct type for each template parameter list (not great).
  • 写回答

9条回答 默认 最新

  • duanfan1869 2013-08-16 15:29
    关注

    You could register a "dict" function in your templates that you can use to pass multiple values to a template call. The call itself would then look like that:

    {{template "userlist" dict "Users" .MostPopular "Current" .CurrentUser}}
    

    The code for the little "dict" helper, including registering it as a template func is here:

    var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
        "dict": func(values ...interface{}) (map[string]interface{}, error) {
            if len(values)%2 != 0 {
                return nil, errors.New("invalid dict call")
            }
            dict := make(map[string]interface{}, len(values)/2)
            for i := 0; i < len(values); i+=2 {
                key, ok := values[i].(string)
                if !ok {
                    return nil, errors.New("dict keys must be strings")
                }
                dict[key] = values[i+1]
            }
            return dict, nil
        },
    }).ParseGlob("templates/*.html")
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(8条)

报告相同问题?

悬赏问题

  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 CSAPPattacklab
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图
  • ¥15 stm32开发clion时遇到的编译问题