jet
jet copied to clipboard
Add internationalization support
Support for internationalization can be done by adding a new token type in the lexer, and an evaluator that would call the translator.Translate passed to the template.ExecuteI18n.
Also add a builtin function trans, a type Translator interface{ Translate(v string,i ...interface{}) error }
I do internationalization in this way: //in handler or add i18n to global functions m := jet.VarMap{} m.Set("i18n", GetText) //func GetText(locale,str string)string{...} Render(ctx, "public/home", m, data) //ctx=*fasthttp.RequestCtx, I use fasthttp and jet template, so fast ;-) //in template {{i18n(user.Locale,"String to translate")}}
Yep, doing it the same way. But it has issues when you're trying to add pluralization because all the libraries out there are using Golang templates under the hood which results in multiple evaluations of template parts. Let's just wait on @jhsx on what he has in mind. :)
@hao1118 How do you use jet templating engine to render to fasthttp? fasthttp does not have response.Writer... I tried jetView.Execute(fasthttp.Response.BodyWriter(), nil, c)
but that renders only body section as string.
@nkev: you can't pass fasthttp.Response.BodyWriter()
. For one, it doesn't belong to an instantiated object/context. It also doesn't belong to a request. Looking at the example at https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp (slightly edited for brevity):
type MyHandler struct {
foobar string
}
// request handler in net/http style, i.e. method bound to MyHandler struct.
func (h *MyHandler) HandleFastHTTP(ctx *fasthttp.RequestCtx) {
t, _ := jetView.GetTemplate("some_template.jet")
t.Execute(ctx, map[string]interface{}, nil)
}
// pass bound struct method to fasthttp
myHandler := &MyHandler{foobar: "foobar"}
fasthttp.ListenAndServe(":8080", myHandler.HandleFastHTTP)
Let's unpack this: fasthttp
's request context already implements the io.Writer
interface (see https://github.com/valyala/fasthttp/blob/b43280dfe8ade44056e0179593f8ab30f82a7f47/server.go#L1002) so you can just pass the context to the template's Execute
function.
Here's a pointer to the relevant documentation in the wiki: https://github.com/CloudyKit/jet/wiki/Rendering-templates.
If you need help, we're on Gitter: https://gitter.im/CloudyKit/jet. :)
@annismckenzie Thank you for taking the time to write the detailed response. Much appreciated!
Happy to help!
hi @nkev, here is my render function:
https://github.com/hao1118/fasthttp-rendering-jet-template
Wow! Including gzip, minification and caching... that's almost a framework, thank you!
ya, almost a framework if having session and database modules. I use "github.com/fasthttp-contrib/sessions" and mongodb "gopkg.in/mgo.v2".
func RenderCache should add support for no-gzip clients(unzip gzipped cache data).
Guys, while I appreciate you exchanging code and ideas I'd suggest moving this to the Gitter chat room because it has nothing to do with this issue. Agreed? :)
@annismckenzie : I just moved the code to my own github page ;-)
A bit of an old topic, but I figured that since it has a relevant solution and since it's still open, it still makes sense to add it here.
I'm wondering if the Translator
interface can be changed, currently it's:
type Translator interface {
Msg(key, defaultValue string) string
Trans(format, defaultFormat string, v ...interface{}) string
}
I'm not sure what Msg()
should do, but Trans()
is a pretty common API that is shared by go-i18n
:
type TranslateFunc func(translationID string, args ...interface{}) string
Currently the translator is accepted, but never used, which sounds like that it's safe to change.
func (t *Template) ExecuteI18N(translator Translator, w io.Writer, variables VarMap, data interface{}) (err error) {
// ..
st.translator = translator
// ..
}
The reason for my request is that I want to influence the function responsible for translation while passing it through to Execute()
, e.g.:
// ..
T, err := svc.tr.Tfunc(locale, formal, user.RegionSettings)
if err != nil {
return false, err
}
err = tpl.ExecuteI18N(T, &writer, nil, nil)
// ..
This way we can keep the templates nice and clean:
{{ T: "my.awesome.key" }}
My current work-around is:
tpl.Execute(html, jet.VarMap{"T": reflect.ValueOf(T)}, nil)
With the template:
{{ T("my.awesome.key") }}