-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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 localization method to Command #1801
Comments
More related issues: #486 #1498 I think there were multiple requests to set version and help description for localisation, but could only find one comment: FYI: @haochuan9421 |
I am interested in localisation, but I think this is a hard problem that will require a lot of code changes and make the code more difficult to write and maintain. So only a maybe, and worth discussing before investing a lot of time in a PR. Somewhat to my surprise, #128 did not get many likes or comments despite being open for six years. (If any readers are interested in localised strings for Commander, please 👍 the opening comment here so we know there is interest!) I do not have experience with localisation in JavaScript.
Have you got an idea of how to handle these? (The parameters, not the plural. That is a separate issue on its own.) In other languages I have used formatting support that allows numbered parameters so translations may change the order of the substituted parameters, like say "too many arguments %1. Expected %2". But I have not found anything native in Node.js that does this.
We did add an organisation recently, so now have somewhere that we could host localisation projects: https://github.com/commander-js [Edit: I currently think we might ship localisations as part of Commander rather than separate packages.] |
Sorry for my slow reply. It does need to change a lot of code to achieve it, so I will be waiting to handle the next step after the discussion result come out. For the issue which how to handle error messages, I found some discussions here: javascript-equivalent-to-printf-string-format |
The keys for the localised strings could be the original text, or an identifier. {
"Hello, world!": "¡Hola Mundo!" // english original as key
} {
helloWorld: "¡Hola Mundo!" // identifier as key
} I slightly prefer the english original as the key, so can see the text and parameters all at once when used. Although for the errors, we do already have the code like Reference: https://www.transifex.com/blog/2015/naming-string-identifiers-best-practice/ |
Numbers and plurals are tricky in general, but I don't think there are many in Commander, perhaps just one:
For interest, the Unicode CLDR has tags for: |
For interest, Yargs uses original string as key, and uses plural tags for (just) https://github.com/yargs/yargs/blob/main/locales/en.json |
Trying out numbered and named parameters: const templated = `error: missing required argument '${name}'`;
const numbered = localise("error: missing required argument '{0}'", name);
const named = localise("error: missing required argument '{name}'", { name });
// or with code as key, and numbered
const coded = localise('commander.missingArgument', name); [Edit, added] Tagged Template per #1801 (comment) const taggedTemplate = localise`error: missing required argument '${name}'`; |
There are lots of interpolation conventions! This guide includes three different examples:
We have simple message strings and don't need extra characters to avoid false matches, so |
This is not quite all the strings, but most of them. Help
suggestSimilar
version and help
commander.invalidArgument for argument
commander.invalidArgument for Option
commander.missingArgument
commander.optionMissingArgument
commander.missingMandatoryOptionValue
commander.conflictingOption
commander.unknownOption
commander.excessArguments
commander.unknownCommand
Is it worth localising the author errors too? I guess so.
|
I think I found an appropriate way to deal with interpolation using Tagged templates. The advantage of using tagged templates:
It works by adding a tag to the original template literals: const message = localization`error: unknown command '${unknownName}'${suggestion}`; And all done. Here have a demo in typescript: https://stackblitz.com/edit/typescript-qmax2v?devToolsHeight=33&file=index.ts |
Ah, I have seen Tagged Templates in past, but didn't understand how it would work here. The implementation is a bit subtle and the calling convention is a little unfamiliar at first, but does keep the code very similar using template to construct the string. Interesting. I think the localisation keys will have to use numbers, I think the names get lost in the process. e.g. An overview and example: https://javascript.plainenglish.io/template-literals-and-a-practical-use-of-tagged-templates-58526d525d72 |
At least initially, would the localisation be an opt-in behaviour, or automatic? I can see a few advantages to opt-in:
|
A reminder to myself. Localisation for the error messages will mean there is a better solution than overriding the private routines like |
Sorry for my slow reply. I am not quite sure I understood your thinking. Do you want localisation can follow the user's PC locale preference automatically? I think it's a good idea, I will try to find a way to achieve it. By the way, I change the keys to use numbers like yours e.g. |
I was suggesting we do not do automatic. Require author to select localisation. But I am interested in how automatic might work! For reference, Sindre Sorhus writes lots of small utility packages and has one for os-locale. My quick look was that without spawning a command, it just uses environment variables, which I suspect does not work in native Windows shell. Two problems I can see with automatic locale which do not occur if author sets locale to match their code:
|
Neat! Note that you can construct the lookup key from the string array passed to (Does not matter if my explanation is too vague to understand! The code details don't matter yet.) |
Is there value in letting people supply a partial or complete localisation map themselves, rather than only pick from supplied locales? This would let people change (say) just the help titles. Perhaps to add colour. |
I am excited. 🎉 I am still worried about the code changes and maintenance of the translations, but if there is interest from users then I think it could be worth it. |
Two days? No problem! Please do not feel under pressure to reply quickly. |
Yes, that is the same thing I thought! With the translationMap( But I think it is time to change its name now because we extended its usage ) and the tagged templates, we can give the authors an easy way to fully control template strings and the error messages directly compare to using |
I will do it right away, and I will try to add some new thoughts to it! Thanks for your patience to read it and gave me suggestions! |
The new demo is ready: https://stackblitz.com/edit/typescript-qmax2v?devToolsHeight=33&file=types.ts Mainly neat and added a |
I found angular also use Tagged templates to do localize: https://angular.io/api/localize |
Another package with an API for locale support, both locales and custom strings: https://day.js.org/docs/en/customization/customization |
I am thinking about what to try first. Being able to customise the strings would let people do things themselves without waiting for a full locale/localisation to be available. And does not require us deciding how to store the localisations and when they are loaded, and fallback et al.
I am not sure if the support should be built straight into Command or into another class. I guess start with adding to Command and see whether it takes more than a single property and routine. |
This comment was marked as outdated.
This comment was marked as outdated.
I opened a PR with some experimental work: #1807 I have added calls to the tagged template function for most of the error messages. I have not done the one that needs rethinking due to pasting together pieces of text including plurals. Added |
Even though we can use
.configureOutput()
to configure the output to change the help header and error, but it is not convenient for user to change it entirely ( include error message and help header and etc. ) for localization.I want to add a method to Command like
program.localization('zh_CN')
to change the output template words and error message could be Simplified Chinese entirely.If it is passable to add , I will try to make a PR then.
Related Issues: #128 #774 #1608
Edit from @shadowspawn to readers: please 👍 this comment if you would like localisation support or support for customising strings added to Commander. You don't need to read all the comments!
The text was updated successfully, but these errors were encountered: