Spittal / vue-i18n-extract

Manage vue-i18n localization with static analysis
https://pixari.github.io/vue-i18n-extract/#what-is-it
MIT License
312 stars 86 forks source link

Functionality #42

Closed tasselchof closed 3 years ago

tasselchof commented 5 years ago

Hello!

Except reporting future is your plugin can put missing translations to locale files?

pixari commented 5 years ago

It's not yet planned, but it would be a nice feature. I'll put it on the todo-list. :)

Spittal commented 5 years ago

Hey @tasselchof I just want to make sure I understand what you're asking. You would want the library to actually write in the missing translations into the language files.

For example:

Before running vue-i18n-extract

// component.vue
$t('missing.string')
// en_EN.json
{
  "some.string": "Hello"
}

After vue-i18n-extract

// en_EN.json
{
  "some.string": "Hello",
  "missing": {
    "string": ""
  }
}

If that's the case would you just want the added translation string to be empty when added?

nothingismagick commented 5 years ago

I don’t think you want it to be blank, because then there will be holes in the interface. Better to have the source language than nothing at all.

tasselchof commented 5 years ago

This should not be empty. We have source language, so we just add strings with source language in each language file.

So, in an example of @Spittal after running tool we will have:

// en_EN.json { "some.string": "Hello", "string": "string" }

And somebody who translating can go inside a file and change this string.

pixari commented 5 years ago

That's very good, @tasselchof.

I see a potential problem:

  1. Some keys are missing
  2. You let the library generate "fillers" to fill the gaps ("string": "string")
  3. You run the library and it tells you that you have a complete and valid language file

... 4. But actually it is valid just because it has been filled with fake placeholders.

So probably I would do:

 // en_EN.json
{
"some.string": "%%MissingTranslation%%",
"string": "%%MissingTranslation%%"
}

and then make the library show as "missing translations" also the "%%MissingTranslation%%" placeholders.

What do you think about it?

Do you like this idea @Spittal?

tasselchof commented 5 years ago

Notifications are not so important, like understanding such a phrase in context. Also, you can get this notification simply checking locale of translated string. If you use not keys, but full phrases like:

$('Translate me');

Then in not English locale key simply will be equal to the value and this can generate a notification.

The way you are offering... in fact, you will need to check this % in the start of translation and if it exists do no translate string.

Tools like Poedit works the way I describe (those practices are pretty widely implemented).

nothingismagick commented 5 years ago

So here is a rundown of the options / situations as I see them:

Situations: -1. Missing key in default locale (aka called by dev, key not found) vue-i18n: key not available, will render key in front-end vue-i18n-extract: COULD create key in default locale (and all other locales)

  1. Missing value in default locale vue-i18n: will supply the key in the front-end vue-i18n-extract: opportunity for option action below
  2. Missing key in (non-default) locale file vue-i18n: will supply the key (or value if availabe) in the front-end vue-i18n-extract: could create key AND value in locale file (as with -1 & 2)
  3. Missing value in (non-default) locale file vue-i18n will supply the value of the default language vue-i18n-extract: could create value in locale file

Options: A. Leave blank (default), front end is resolved by vue-i18n according to above situations B. Clone default language value => has the downside of putting false-positives in the collection / changing statistics (and would need to be double parsed) C. Copy key to value => also potentially full of false positives D. Placeholder '%%key_missing%%' => parseable by vue-i18n-extract (and vue-i18n unfortunately)

Discussion: Tools like crowdin and weblate won't know the difference between a real translation and any of B, C or D. In cases where translators are paid via statistical analysis, the latter 3 will change their job from translation to correction, which is generally less well-paid. Further, this makes the first pass of a translation job that much easier to mess up because the interface on those tools will show all of the strings as already translated.

At any rate, I think that the dev should be in charge of how they want this handled (if at all) and should therefore be fully optional - in a sense like different degrees of logging errors as commonly seen in many types of software.

enzonotario commented 5 years ago

Hi folk! Did you found a way to extract all missing strings to a json, for example?

Thanks in advance!

civicwar commented 5 years ago

@enzonotario Hello, you have a CLI option -o to extract a json file.

[--output, -o] Use if you want to create a json file out of your report.(ex. -o output.json)

enzonotario commented 5 years ago

Thanks! but I need just the missing keys, so I have created a node script like:

const VueI18NExtract = require('vue-i18n-extract').default;
const report = VueI18NExtract.createI18NReport(config.jsDir + '/**/*.?(js|vue)', config.i18nDir + '/*.?(js|json)');

// missing keys are in report.missingKeys
ray007 commented 4 years ago

Maybe not exactly what you want, but since I have to do the actual translations with sisulizer anyway, just getting a json-file as blueprint works fine for me. Doing that with:

const VueI18NExtract = require('vue-i18n-extract').default,
    fs = require('fs'),
    items =  VueI18NExtract.parseVueFiles('src/**/*.?(js|vue)');

var result = {}, i = 0;

items.forEach(item => {
    let path = item.path, parts = path.split('.'), o = result, prop = parts.pop();
    parts.forEach(name => {
        if (!(name in o)) o[name] = {};
        o = o[name];
    });
    if (!(prop in o)) {
        o[prop] = path;
        i++;
    }
});

fs.writeFileSync('i18n/msgs.json', JSON.stringify(result));
console.log(`found ${i} keys`);

Maybe something for an example in case somebody else finds it useful too?

erickwilder commented 4 years ago

Although the library containsextract in its name I confess this was the number 1 reason I came across it. Translation extraction is something that depends a lot on the context you build your project. Perhaps this project should limit itself in proving ways to make it easier for people to build this kind of feature themselves using the Node API.

Some things to consider:

To build a standalone extraction solution, these have to be figured out:

pixari commented 4 years ago

Hi @erickwilder,

I find your observations right. It isn't easy at all to build a generic extraction tool that could cover all the formats and the edge cases.

When I started it wanted to solve a specific problem covering specific requirements.

Then it grew up getting more flexibility and a bunch of options, but this doesn't make it a standalone extraction solution.

What is happening is that people are extending the library making it working with more custom formats,.for example.

That's why I don't believe that it can be a superic solution, but more kind of collection of specific solutions.

What would you suggest?

gapon2401 commented 4 years ago

Hi! I wrote small package for exporting missed strings from the report to json locale files. Works fine for my projects. Hope, it helps somebody. vue-i18n-extract-translations Still waiting for official release with that feature.

pixari commented 4 years ago

@gapon2401 would you like to integrate that feature in the library?

pixari commented 3 years ago

This is probably obsolete now.