Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add internationalization support #3

Open
jhsx opened this issue May 9, 2016 · 12 comments
Open

Add internationalization support #3

jhsx opened this issue May 9, 2016 · 12 comments
Labels

Comments

@jhsx
Copy link
Member

jhsx commented May 9, 2016

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 }

@jhsx jhsx added this to the Release 2.0 milestone Jul 13, 2016
@jhsx jhsx added feature and removed enhancement labels Jul 13, 2016
@jhsx jhsx changed the title Add support for internationalization Aka i18n Add internationalization support Jul 14, 2016
@jhsx jhsx modified the milestones: Release 2.1, Release 2.0 Aug 14, 2016
@jhsx jhsx removed this from the Release 2.1 milestone Sep 8, 2016
@hao1118
Copy link

hao1118 commented Oct 1, 2016

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")}}

@annismckenzie
Copy link
Member

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. :)

@nkev
Copy link

nkev commented Oct 12, 2016

@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.

@annismckenzie
Copy link
Member

@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. :)

@nkev
Copy link

nkev commented Oct 12, 2016

@annismckenzie Thank you for taking the time to write the detailed response. Much appreciated!

@annismckenzie
Copy link
Member

Happy to help!

@hao1118
Copy link

hao1118 commented Oct 13, 2016

hi @nkev, here is my render function:

https://github.com/hao1118/fasthttp-rendering-jet-template

@nkev
Copy link

nkev commented Oct 13, 2016

Wow! Including gzip, minification and caching... that's almost a framework, thank you!

@hao1118
Copy link

hao1118 commented Oct 13, 2016

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).

@annismckenzie
Copy link
Member

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? :)

@hao1118
Copy link

hao1118 commented Oct 13, 2016

@annismckenzie : I just moved the code to my own github page ;-)

sauerbraten added a commit to sauerbraten/jet that referenced this issue Feb 4, 2020
@Dynom
Copy link

Dynom commented Oct 21, 2020

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") }}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants