如何在golang中向已解析的模板中添加FuncMaps?

huangapple go评论75阅读模式
英文:

How can I add FuncMaps to already parsed templates in golang

问题

我有一些模板,最初在应用程序启动时进行解析(显然是为了加快速度)。

var templates = template.New("template")

filepath.Walk("views", func(path string, info os.FileInfo, err error) error {
    if strings.HasSuffix(path, ".html") {
        templates.ParseFiles(path)
    }

    return nil
})
log.Println("Templates Parsed")

然后,我有一个函数映射,它们在自己的函数中添加(因为我需要请求对象,以便获取会话数据,如下所示)。

func View(w http.ResponseWriter, r *http.Request, tmplN string, data interface{}) {

    tmpl := templates.Funcs(template.FuncMap{
        "username": func() string {
            session := Sesh(r)
            username := ""
            if session.Values["username"] != nil {
                username = session.Values["username"].(string)
            }
            return username
        },
        "authenticated": func() bool {
            session := Sesh(r)
            authenticated := false
            if session.Values["authenticated"] != nil {
                authenticated = session.Values["authenticated"].(bool)
            }
            return authenticated
        },
    })

    err := tmpl.ExecuteTemplate(w, tmplN, data)
    if err != nil {
        log.Println("Error " + err.Error())
    }
}

但是,如果我不在模板解析之前调用Funcs函数,它似乎不起作用,例如,如果我尝试在我的register模板中使用如下所示:

{{ define "register" }}
    {{ template "_header" .}}

       {{ if authenticated }}
           // 调用 FuncMap 函数
       {{ end }}
<br/>
<br/>
<br/>
<div class="row align-center">
    <div class="large-4 columns text-center">
        <div id="RegistrationFormComponent"></div>
    </div>
</div>
    {{ template "_footer" .}}
{{ end }}

我会得到一个错误,提示“register”不存在,因为当它尝试解析时,函数authenticated会抛出一个错误。如果有关如何使其按预期工作的任何信息,将非常感谢。

英文:

I have my templates which are initially parsed on the app launch (obviously for speed reasons like this)

var templates = template.New(&quot;template&quot;)

filepath.Walk(&quot;views&quot;, func(path string, info os.FileInfo, err error) error {
		if strings.HasSuffix(path, &quot;.html&quot;) {
			templates.ParseFiles(path)
		}

		return nil
})
log.Println(&quot;Templates Parsed&quot;)

Then I have my funcmaps which get added in their own function (because I need the request object so I can get their session data like so)

func View(w http.ResponseWriter, r *http.Request, tmplN string, data interface{}) {

	tmpl := templates.Funcs(template.FuncMap{
		&quot;username&quot;: func() string {
			session := Sesh(r)
			username := &quot;&quot;
			if session.Values[&quot;username&quot;] != nil {
				username = session.Values[&quot;username&quot;].(string)
			}
			return username
		},
		&quot;authenticated&quot;: func() bool {
			session := Sesh(r)
			authenticated := false
			if session.Values[&quot;authenticated&quot;] != nil {
				authenticated = session.Values[&quot;authenticated&quot;].(bool)
			}
			return authenticated
		},
	})

	err := tmpl.ExecuteTemplate(w, tmplN, data)
	if err != nil {
		log.Println(&quot;Error &quot; + err.Error())
	}
}

But it seems like if I don't put the Funcs call before the parsing of the templates it doesn't work, e.g. if I try to use in my register template like so:

{{ define &quot;register&quot; }}
    {{ template &quot;_header&quot; .}}

       {{ if authenticated }}
           // Call FuncMap function
       {{ end }}
&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;div class=&quot;row align-center&quot;&gt;
	&lt;div class=&quot;large-4 columns text-center&quot;&gt;
        &lt;div id=&quot;RegistrationFormComponent&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;
    {{ template &quot;_footer&quot; .}}
{{ end }}

I get an error that "register" does not exist because the function authenticated throws an error when it's trying to parse it. Any information on how I can get this to work as intended would be great thanks.

答案1

得分: 2

所以我找到了解决方法,但我会将这个答案留在这里,因为似乎没有地方回答,基本上我可以定义一个冗余的FuncMap,模仿我将在会话中使用的那个,并且只返回空白,然后我可以用我的view函数中的FuncMap(在问题帖子中可见)覆盖它们,像这样:

var templates = template.New("template").Funcs(template.FuncMap{
    "authenticated": func() bool {
        log.Println("Was I called?")
        return false
    },
    "username": func() string {
        return ""
    },
})
英文:

So I figured it out, but I'll leave this answer here as it seems to not be answered anywhere, basically I can define a redundant FuncMap that mimics the one I will be using with the sessions, and just return them blank, I can then overwrite them with the FuncMap from my view function (visible in the question post) like this:

var templates = template.New(&quot;template&quot;).Funcs(template.FuncMap{
    &quot;authenticated&quot;: func() bool {
        log.Println(&quot;Was I called?&quot;)
        return false
    },
    &quot;username&quot;: func() string {
        return &quot;&quot;
    },
})

huangapple
  • 本文由 发表于 2015年12月30日 13:55:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/34523745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定