-
Couldn't load subscription status.
- Fork 8
Version 2 #60
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
base: main
Are you sure you want to change the base?
Conversation
|
@dcdunkan are you still interested in working on this? If there is a chance that this will be abandoned, then I won't spend so much time reviewing it |
|
Yes, I am still interested in working on this. Sorry, I got busy with some things in the offline life. I expect to get back on this in one or two weeks' time. |
|
Other than for the work on the suggestion Loskir made on making the CLI extendable to allow type generation for arbitrary formats, I think the current state is ready for an initial review. |
i18n plugin v2 introduces a lot of changes, mostly breaking. The following is the list of major changes made:
No longer bound to a specific syntax / l10n system
There is now the concept of "Adapters" much like session storage adapters. There will be few official ones, and it should be easy to make a custom one. Adapters can be directly plugged into an i18n instance, and they should just work. Adapters should expose
localesregistered and a translate function that of the signaturetranslate(locale, message, variables?).The system we currently we have built-in to i18n is Fluent. This will be converted to an official adapter. This adapter system allows to bring back the JSON system we had in pre-1.0 since lot of people still uses it. Other than these two, we could also bring support for GNU getttext PO files, or JSON based ICU MessageFormat, I18nnext format, or any other format as official or unofficial adapters.
The reasons for this change are,
message.attribute(2 level depth). Now its possible to have deeply nested messagesconversations.greeting.initial-message.help-button(just saying that it's possible, no intention to recommend this).Example adapters:
Strict TypeScript types Support
Optional, but recommended of course. Type messages and pass it as a generic type param. TS gives full typings for locales (optional), messages, variables. It can even restrict passing any variables to message requiring no variables. Although, I'd like to know general DX on this one.
It tends to be really strict. Syncing the typings with the translations can be really hard, with all the variables and their types, etc. So, v2 introduces,
Type Generation through CLI
There is also a CLI with (possibly more) tools related with i18n. It's written using Deno APIs as there is a watch mode.
cli/main.tsis the entry point.generate-typessubcommand:--format: specify the format to use. e.g., fluent.--output/-o: output file to write the types to.--watch: watch the concerned files.There are two modes: locales directory and list of files to watch.
--locales-dirwhich is the path to locales directory and--fallbackwhich should be the locale to focus, it should be a directory inside the--locales-dir. Just the name of the directory is enough.Possible improvements: Useful i18n tools like, linting or checking for errors like overriding and stuff. Or source analysis to find messages that are not referenced in code.
Locales directory & loading
Loading locales directories used to be a method of the main
I18nclass, but no longer. Also uses node:fs for more cross-runtime compatibility (except for Cloudflare workers). It lies under a different module.loadLocalesDirectoryis now a function that takes in anResourceLoadable(has methodloadResource) and some options. It walks through the specified directory, and adds those sources to the adapter.loadLocalesDirectoryis now a little bit more standardized. Example structure:Locales are now separated as directories, and not as single files. Can be nested and all. Common files, although I can't really say that I'd use it a lot, but we can have them. Common files will be treated as one of the locale sources files, so will be added to each locale.
Possible addition: Could introduce namespacing like i18nnext. (e.g., supporting categorised (namespaced) keys like rewards:message, commands:start, commands:start.button).
Users can always resort to the old structure, where single files were considered as locales: en.ftl, de.ftl, etc, by writing their own simple functions to load to the adapter:
Or this can be built-in if needed.
Other stuff
Got rid of warning handlers (it didn't feel useful). And introduced a simple handler option for handling "missing key" events. If the handler returns a string, it's returned as the translate message. If not, continued to next negotiated locale. If still didn't match, fell back to fall back locale. If still not, an error is thrown! (Because fall back locale must have all the messages one references). Need to discuss this error throwing.
There is no ultimate fallback locale like we used to have (en). The user should set a reliable fallback locale on their own. Less surprises when it errors.
JSR compatible, except for grammY v1 imports; thought of replacing after grammY v2 is closer to completion, assuming
ContextandMiddlewareFnhave not changed much in v2.Removed session dependency. Use locale negotiators. (plugins: remove i18n→sessions dependency #57)
I18nFlavoris now transformative (for v2). (chore: make context flavor transformative #58)Documented almost everything.
Lots of tests.