Conversation
This was
linked to
issues
May 24, 2025
Member
|
@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 |
Member
Author
|
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. |
Member
Author
|
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. |
* Any valid format module that exports a valid configuration can be used * Follows a new directory structure for adapters * Used `citty` for CLI
* extracted the message variables to a type * implemented hears filter middleware as i18n instance method.
flexibility!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.