eldarc / vue-i18n-gettext

Full-featured gettext support for Vue.js.
MIT License
9 stars 0 forks source link

This plugin usuable yet? #50

Open kngai opened 6 years ago

kngai commented 6 years ago

Hi @eldarc,

I'm quite interested in such a gettext extractor and compilor for vue-i18n. Is this ready to be used?

I was looking at https://github.com/eldarc/vue-i18n-gettext/tree/master/examples/full-demo and trying to mimic that setup on my Vue project, but I wasn't able to get it working (getting 0 messages extracted).

eldarc commented 6 years ago

@kngai We've been using it in production for few months. It works, but has issues that I want to fix before making it ready for use as a public plugin. I started rewriting parts of it. I don't have any estimates when it will be finished.

However, you can take a look at this: https://github.com/eldarc/test-vue-i18n-gettext

This is a working example with the currently released plugins.

Key files and directories to take a look: ./config/i18n.js (config of the localization) ./build/gettext.js (extraction script) ./locales (directory for .po files and the compiled translations.json file) ./src/main.js (plugin used) ./src/router/index.js (router in history mode) ./package.json (gettext script defined)

In this example you run the command yarn gettext or npm run gettext and it will extract strings.

Please let me know if this helped.

kngai commented 6 years ago

Thanks @eldarc

I was able to get my application working with that setup.

Question:

Some comments/notes on my end:

eldarc commented 6 years ago

@kngai First of all thank you for trying out the plugin at this stage.

For the plural for the currently released version it should be:

<translate :t-n="count" t-plural="%{count} cars">%{count} car</translate>

I added this to the example repository (https://github.com/eldarc/test-vue-i18n-gettext)

However, in the new version that I'm working on it will be something like this:

<t x="%{count} car" plural="%{count} cars" n="count"/>

same for the singular

<t x="A string"/>

translate and t will be both acceptable. And <t>A string<t> will also be valid.

The directive v-translate will be completely removed since I didn't find any advantages compared to using the component.

As for the extraction, it was intended to be adjustable, we even did automatic syncing with POEditor. So your configuration is great if it works for you and your translators.

I'm also rewriting the vue-gettext-tools plugin, basically writing a custom parser so that it can parse many different Vue setups.

A lot of work ahead, so please feel free to report anything and ask questions. The goal is to make really a full-featured plugin.

At the beginning I used vue-i18n but later did more optimizations until it was not needed. If you have any suggestions for a new name, please suggest. vue-gettext and gettext-vue are both taken. I was thinking about vue-tx so that it has a connection to the new format <t x="string"/>. Thoughts?

eldarc commented 6 years ago

@kngai Just to add something.

You said:

That way, I can send the send dictionary.pot off for official translations before compiling.

I would recommend that you send .po files to translators. The plugin should generate a .po file for each locale you defined. If you defined en and de, then you should have en.po and de.po. The de.po should be send to the German translator.

The .pot is used as a registry of found strings inside the source files, then it's compared to translated .po files. If a string is present in the .po file but not in dictionary.pot it will be deleted from .po. dictionary.pot is generated each time from blank.

The compilation process then takes all .po files and generates a translations.json file which is used in the app.

kngai commented 6 years ago

@eldarc Thanks again. Got the plural working.

In terms of using the new <translate> or <t>, I like it. That shorthand will help shorten things, although I'll likely keep using <translate> so if a brand new developer takes over my app, it be easier to know what the tag is.

Follow up question: What about annotating strings in JS? I'm using https://github.com/Polyconseil/vue-gettext#1b-annotating-strings-in-javascript-code-js-or-vue-files as reference. Perhaps you can update the README file to show the examples you have currently, so I don't have to keep bugging you :)

Perhaps I just like simple/self-descriptive names, but I like the t-name property names more. So:

I find those will keep consistent with the vue-tx module name your thinking. Other module name ideas off the top of my head:

I think having gettext in the name is important, as I associate gettext with generating .pot or .po files, which this plugin certainly does.

As for your note on sending the .po file to the translator, you're right. I wrote that wrong. When I initially create the .po file, I normally open the .pot file in Poedit, set the language I'm translating to (fr_CA), and then send to translator. When updating text changes, I would npm run gettext-extract, open the existing fr_CA.po in Poedit, and then go to "Catalog" -> "Update from POT file...". Hence why I broke up gettext.js as I like updating the changes manually.

Which reminds me, when I first tried creating the fr.po file through ./build/gettext.js, I think the encoding wasn't properly set? Accented characters weren't shown properly (plain text; ASCII encoded?). Perhaps I specified just fr instead of fr_CA in the list of locales in ./config/i18n.js. Didn't look too much into it, so sorry for lack of reproducible details. I ended up creating the fr.po file from the generated .pot file through Poedit (set language as fr_CA; French Canadian) and everything was fine for me from there on; my working fr.po is encoded in "UTF-8 without BOM"

Overall, I'm happy for this plugin moving forward. This bundled gettext extractor and compiler tool in one package is what sold me. I'm really thinking of using this in our production environment for our translation process.

eldarc commented 6 years ago

You can use gettext with the vm like this: vm.$gettext(msgid); this.$gettext(msgid) vm.$ngettext(msgid, plural, n); this.$ngettext(msgid, plural, n) vm.$pgettext(context, msgid); this.$pgettext(context, msgid) vm.$npgettext(context, msgid, plural, n); this.$npgettext(context, msgid, plural, n)

If you want comments inside .po files for specific strings you can define them like this: this.$gettext('string') // $t: This is a comment or

// $t: This is a comment
this.$gettext('string')

For interpolation (this needs some testing to see how it behaves): this.$_i(msgid, values), this.$_i(this.$gettext('{car} car', {car: 'nice'})

or if you have count defined in the component this.$_i(this.$gettext('{car} car', this)

Please keep in mind that if you want to use those strings without needing to refresh the whole app once the language is switched you need to define them in computed. If you define them in data those will be not reactive, so when you change the language the one that was selected on the initial load will stay. You can set forceReloadOnSwitch to true in the i18n config if you want to force reload when switching languages (if you choose to use it in data)

For using formatting: this.$number(number, options) or this.$_n (this will format the number to the currently selected locale format) this.$date(date, options) or this.$_d (this will format the date to the currently selected locale format) this.$currency(value, options) or this.$_c (this will format the price to the format of the currently selected locale and currency.) this one has some more configuration options with the plugin, but it isn't that much tested at this moment.

Those methods use Intl.NumberFormat (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat) and options accept settings for that constructor.

If you are passing the router to the plugin you can access the automatically modified routes like this: this.$i18nRoutes. To change the active locale use this.$changeLocale(locale). Everything else is with this.$i18n like the config, or active locale this.$i18n.activeLocale.

Thanks @kngai for the name suggestions.

I will try to see if I can reproduce some of the encoding issues, at the moment I can't remember that I came across something similar. Let me know if you have some more details.

Yeah you right that I should write some documentation, but will try to do so once I publish the first new version with a working full example demo. A lot of work to do before I can be sure that is safe for all users.