-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Open
Labels
DocumentationIssues describing a change to documentation.Issues describing a change to documentation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone
Description
Hi,
I would like to see an example for translated html/template with x/text/message.
Here's my current attempt with two different calling styles (free to use):
package main
import (
"bytes"
"fmt"
"golang.org/x/text/language"
"golang.org/x/text/message"
"golang.org/x/text/message/catalog"
"html/template"
)
type TrPage struct {
contents string
trcat catalog.Catalog
}
type TrTemplate struct {
funcs template.FuncMap
base string // Base template as string
pages map[string]TrPage // Pages which uses base template
}
func New(base string, funcs template.FuncMap) (TrTemplate, error) {
return TrTemplate{
base: `{{define "base"}}` + base + `{{end}}`,
pages: make(map[string]TrPage),
funcs: funcs,
}, nil
}
func (t *TrTemplate) AddPage(name string, template string, translations catalog.Catalog) error {
tp := TrPage{
contents: `{{define "content"}}` + template + `{{end}}`,
trcat: translations,
}
t.pages[name] = tp
return nil
}
func (t *TrTemplate) Render(templatename string, language language.Tag, data interface{}) (out string, err error) {
var tmp bytes.Buffer
tpl := template.New(``)
tpl.Funcs(t.funcs)
tpl.Funcs(template.FuncMap{
// Translate inside template
`T`: func(s string, a ...interface{}) template.HTML {
pr := message.NewPrinter(language, message.Catalog(t.pages[templatename].trcat))
return template.HTML(pr.Sprintf(s, a))
},
})
_, err = tpl.Parse(t.base)
if err != nil {
return ``, err
}
_, err = tpl.Parse(t.pages[templatename].contents)
if err != nil {
return ``, err
}
err = tpl.ExecuteTemplate(&tmp, `base`, data)
if err != nil {
return ``, err
}
return tmp.String(), nil
}
type myBaseStruct struct {
Title string // Base title
Language string
C interface{} // per-page content variables
}
type myAboutPageStruct struct {
User string
Msg string
}
func main() {
// Common functions for templates (for example CSRF generation)
funcs := template.FuncMap{
}
basetpl, err := New(baseHTML, funcs)
if err != nil {
panic(err)
}
// Translate template to this language
useLanguage := language.Finnish
//useLanguage := language.English
// Front page
frontpageCat := catalog.NewBuilder(
catalog.Fallback(useLanguage),
)
basetpl.AddPage(`frontpage`, frontpageHTML, frontpageCat)
// About page
aboutCat := catalog.NewBuilder(
catalog.Fallback(useLanguage),
)
aboutCat.SetString(language.Finnish, `about_page_user`, `Tietoa käyttäjästä %s`)
aboutCat.SetString(language.English, `about_page_user`, `Information about user %s`)
basetpl.AddPage(`about`, aboutHTML, aboutCat)
printer := message.NewPrinter(useLanguage, message.Catalog(aboutCat))
out, err := basetpl.Render(`about`, useLanguage, myBaseStruct{
Title: `yay title`,
Language: useLanguage.String(),
C: myAboutPageStruct{
// Style 1
User: `test user`,
// Style 2
Msg: printer.Sprintf(`about_page_user`, `test`),
},
})
if err != nil {
panic(err)
}
fmt.Print(out)
}
var baseHTML = `
<!DOCTYPE html>
<html lang="{{.Language}}">
<head>
<meta charset="UTF-8">
<title>{{.Title}}</title>
</head>
<body>
This is base
Content:
{{template "content" .C}}
</body>
</html>
`
var aboutHTML = `
<div>
<!-- Style 1 -->
{{T "about_page_user" "{{.User}}" }}
<!-- Style 2 -->
{{.Msg}}
</div>
`
var frontpageHTML = `
<div>
This is frontpage
</div>
`Which calling style is recommended or is there third option?
Style 1 also doesn't evaluate {{.User}} to test user (I don't know how).
I would like to see style 1 to be used.
Also the parser for html/template is hidden as internal so you can't build nice automated translated token gatherer script for these kind of tasks to find all T calling functions and dump those to a translation file. Are there plans to open it up?
I would also like to see example for when you have to add some HTML to a translation such as:
someCatalog.SetString(language.Finnish, `about_page_user`, `Tietoa käyttäjästä %s`)
and %s is for example <a href="/foo">{{.User}}</a>.
kdisneur, boutros, jehiah, josuebrunel and larrasket
Metadata
Metadata
Assignees
Labels
DocumentationIssues describing a change to documentation.Issues describing a change to documentation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.