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

Reuse existing translation #12

Open
labibramadhan opened this issue Sep 9, 2017 · 2 comments
Open

Reuse existing translation #12

labibramadhan opened this issue Sep 9, 2017 · 2 comments

Comments

@labibramadhan
Copy link

labibramadhan commented Sep 9, 2017

Can i reuse existring translation? For example something like this:

en:
  greeting: Hello
  greetMySelf: {{.en.greeting}} me!
@labibramadhan
Copy link
Author

labibramadhan commented Sep 9, 2017

I can resolve by writing this:

I18nTranslations := make(map[string]map[string]string)

translations := Globals.I18n.LoadTranslations()

for lang, locales := range translations {
  I18nTranslations[lang] = make(map[string]string)
  for localeKey, translation := range locales {
    I18nTranslations[lang][localeKey] = translation.Value
  }
}

output := Globals.I18n.T(
  "greeting",
  "en",
  I18nTranslations,
) 

but it doesn't resolve for cases that the reusable translations has parameters, for example:

en:
  greeting: Hello, good {{.Time}}
  greetMySelf: {{.en.greeting}} for me!

that should output: Hello, good evening for me! with arg: map[string]string{"Time": "evening"}

and it doesn't resolve for cases that the reusable translations is a nested variable, for example:

en:
  greeting:
    morning: Hello, good morning
    evening: Hello, good evening
  greetMySelf: {{.en.greeting.morning}} for me!

@bodhi
Copy link
Member

bodhi commented Sep 11, 2017

@labibramadhan when using i18n on an app, it's a good idea to use full strings as messages. Building up messages from other small messages has 2 main disadvantages:

  1. It makes the logic for translations difficult to follow, and couples messages together
  2. It's often not flexible enough to allow translators to correctly translate the message. The context of the original message often affects the inflection of the parts of the message.

That said, your idea of nesting translations is an interesting one, but as you've discovered, translations don't compose very well. A translation is not just the original message, it's the message plus substitutions (variables).

So to compose two messages into a new one, you need the new message and possible variables from any sub-messages:

en:
  greeting: Hello, good {{.Time}} <= `greeting` id + `.Time` variable
  greetMySelf: {{.en.greeting}} for me! <= `greetMySelf` + (`greeting` id + variables from `.en.greeting`: `.Time`)

Since the messages are translated at run-time you need to localise the messages multiple times to "get to the bottom" of the translation nesting:

  1. Get en translation for greetMySelf.
  2. Discover that the translation contains en.greeting
  3. Get en translation for greeting <= recursion!
  4. Discover that greeting doesn't reference other translations
  5. ...

Also, since languages will reuse messages in different ways, you don't even really know which variables you will need, so you then either need to manually inspect the message nesting, or make all possible variables available.


If instead of reusing translations, you just want to include translated messages in other message, you can translate the message and provide it manually as a substitution:

en:
  greeting:
    morning: morning
    text: Hello, good {{.Time}}
  greetMySelf: {{.en.greeting}} for me!


time := t("greeting.morning")
g := t("greeting.text.", { "Time": time })
output := t("greetMySelf": { "greeting": g })

This is basically the same as my recursion example above, but you're doing it by hand instead of the library doing it for you.

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

No branches or pull requests

2 participants