Closed sabsaxo closed 6 years ago
What exactly you're trying to make?
The translation shouldn't be available all the time. You can dynamically load a chunk (a translation), for instance, with Webpack — it will move translation file into a separate bundle and load it only when you require it.
Then you just need to register loaded locale and set the language to registered locale:
This is not super accurate code, but you can get the idea:
const loadLocale = async (locale) => {
// As far as I can remember, in latest Webpack `import` marks a standalone chunk
const po = await import(`${localesPath}/${locale}.json`)
gt.addTranslation(locale, 'messages', po)
gt.setLocale(locale)
}
// ...
// somewhere in your component you're calling it when user changes locale
<button @click='loadLocale('de')'>DE</button> // will load only `de.json` bundle
<button @click='loadLocale('es')'>ES</button> // will load only `es.json` bundle
Now, you should take into consideration, that node-gettext
isn't backward-reactive. When you will load specific locale and set it as currently active, you will need to re-render your components with current settings, to ensure that now node-gettext
will execute gt.gettext()
with a current active locale.
In other words, what you need is code splitting and dynamic imports.
Well, that's pretty much what I do now. I use a precompiled handlebars template that receives a data object when rendered:
let data = {
title : gt.gettext('The title'),
label : gt.gettext('A random label')
};
But when I change the locale on gt and re-render the template, it still shows the original english strings ... so I'm quite confused about where to look for issues. I can see the the catalogs get set properly in gt, but the gt.gettext() does nothing ... ?
And by the way, you add po as the first parameter (which should be the locale as a string, and data is not set – I know this isn't 'super accurate code' but just to make sure I'm not making any mistakes. According to the docs, the first parameter is the locale as a string, the second parameter the domain and the third parameter the actual translations as a JSON object.
…
gt.addTranslations('sv-SE', 'messages', swedishTranslations)
gt.setLocale('sv-SE')
…
Oh, and I see now that addTranslations actually ADDS translations ... but that again bloats the app – everytime the user changes language it gets added to the catalog (memory consumption). How can I have only ONE translation in the catalog at a time (apart from clearing the catalog myself)?
OK, when setting debug to true I get:
No translation was found for msgid "Login" in msgctxt "" and domain "messages"
Now, that's confusing; why suddenly 'msgid' and 'msgctxt'? I have my catalog in JSON-format ... pure key / value pairs ... !?
I'm not using any .po or .pot files in the browser ... how can I make node-gettext use pure JSON catalog?
Yeah, made sure to use the correct gettext-parser format from here on ... : )
Can you explain to me why 'No translation was found ...' by looking at the attached image? I simply cannot figure out why it won't work.
And even though I use gettext-parser, I don't get the same file structure as in the gettext-parser README file example. I don't have a 'translations' entry in my JSON file ... so something seems to be not working correctly in the relationship between gettext-parser and node-gettext?
So, that issue seems to be related to #43? Is it still not working?
Oh, and I see now that addTranslations actually ADDS translations ... but that again bloats the app – everytime the user changes language it gets added to the catalog (memory consumption). How can I have only ONE translation in the catalog at a time (apart from clearing the catalog myself)?
I'm not sure that node-gettext
has any built-in means to manage this, but I wouldn't delete already loaded translation (if they are loaded dynamically, on demand, and not at once), otherwise, you will force users to re-download locale if they will decide to switch locale back and forth.
But if you really wont to do this, it is trivial to manage manually, since all gettext instance is exposed to you, and you can simply use delete
operator to remove object property with no longer needed translation.
And by the way, you add po as the first parameter (which should be the locale as a string, and data is not set – I know this isn't 'super accurate code' but just to make sure I'm not making any mistakes. According to the docs, the first parameter is the locale as a string, the second parameter the domain and the third parameter the actual translations as a JSON object.
Yeah, I've mistyped it. It had to be
- gt.addTranslation(po, 'messages', data)
+ gt.addTranslation(locale, 'messages', po)
Yes, managed to mix up the issues. All is good, and I can also clean the catalogs if I decide to. Thanks.
The problem with all this localization is that ALL languages seem to be spit into the application like:
Problem is; that load ALL translation files into the application ... not good!
So I'm trying to do this in a more dynamic way (client side wise – to ONLY have the language needed loaded in the browser).
So, the user select a language from a drop down (forget about the default language for now), the server response with a JSON object that I attach to the gettext (async) by:
'gt' is my gettext instance 'data', is the returned JSON object
This SEEMS to work just fine. The problem I'm left with is how to make the actual translation happen. As far as I understand the gt.gettext('String here'), is ONLY used to extract strings to be translated. But how do I actually translate the strings on the client dynamically? That seems to baffle me a lot with gettext. I'm pretty surpriced that this seems to be so hard to find any info about ... or maybe it's just because I expect gettext to be more clever than it actually is ... seems weird that ALL translations have to be available at all times ... as if we were still coding applications to be run from an installtion on a hard drive.