Go Code

This way to call a function from a Go template can be used for many purposes. This is only one tiny example how it works. It may be possible to calculate values etc.

1. Write the HTML and call the function "lang" with parameters

<p>{{lang "Company"}}</p>   //Hardcoded
<p>{{lang .}}</p>  // can also be a parameter
                

2. Tell the templates to use the function "lang"

func init() {
    tpl = template.Must(template.New("").Funcs(template.FuncMap{
        "lang": lang,
    }).ParseGlob("./public/tmpl/*.html"))
}
        

3. Create the function

func trans(key string) string {
    path := "locale/" + usr_lang + ".po"
    translationsMux.Lock()
    po, ok := translations[usr_lang]
    if !ok {
       po = gotext.NewPo()
       po.ParseFile(path)
      translations[usr_lang] = po
    }
    translationsMux.Unlock()
    return po.Get(key)
}
                    

4. All Go code put together and fetch the stored language from a cookie

    package main

    import (
        "html/template"
        "net/http"
        "strings"
        "sync"
    
        "github.com/leonelquinteros/gotext"
    )
    
    var tpl *template.Template
    var translations map[string]*gotext.Po
    var translationsMux sync.RWMutex
    var usr_lang string
    
    func init() {
        translations = make(map[string]*gotext.Po)
        languages := []string{"en", "fr", "de", "es", "it"}
        for _, lang := range languages {
            path := "locale/" + lang + ".po"
            langPo := gotext.NewPo()
            langPo.ParseFile(path)
            translations[lang] = langPo
        }
        tpl = template.Must(template.New("").Funcs(template.FuncMap{
            "trans": trans,
        }).ParseGlob("./public/tmpl/*.html"))
        http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./public/img"))))
        http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./public/css"))))
        http.Handle("/icn/", http.StripPrefix("/icn/", http.FileServer(http.Dir("./public/icn"))))
        http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("./public/js"))))
        http.Handle("/misc/", http.StripPrefix("/misc/", http.FileServer(http.Dir("./public/misc"))))
    }
    
    func trans(key string) string {
        path := "locale/" + usr_lang + ".po"
        translationsMux.Lock()
        po, ok := translations[usr_lang]
        if !ok {
            po = gotext.NewPo()
            po.ParseFile(path)
            translations[usr_lang] = po
        }
        translationsMux.Unlock()
        return po.Get(key)
    }
    
    func usr_getlang(r *http.Request) string {
        lang, _ := r.Cookie("lang")
        if lang != nil {
            usr_lang = lang.Value
        } else {
            usr_lang = "en"
        }
        return usr_lang
    }
    
    func main() {
        http.HandleFunc("/", endpoint)
        http.ListenAndServe(":9086", nil)
    }
    
    func endpoint(w http.ResponseWriter, r *http.Request) {
        path := strings.Trim(r.URL.Path, "/")
        usr_getlang(r)
    
        var page string
        switch path {
        case "robots.txt":
            http.ServeFile(w, r, "public/misc/robots.txt")
        case "sitemap.xml":
            http.ServeFile(w, r, "public/misc/sitemap.xml")
        case "favicon.ico", "favicon-32x32.png", "favicon-16x16.png":
            return
        case "":
            page = "home.html"
        default:
            page = path + ".html"
        }
    
        tpl.ExecuteTemplate(w, page, nil)
    }