Skip to content
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

i18n in kanidm #2105

Open
pontaoski opened this issue Sep 11, 2023 · 20 comments · May be fixed by #2107
Open

i18n in kanidm #2105

pontaoski opened this issue Sep 11, 2023 · 20 comments · May be fixed by #2107
Labels
enhancement New feature or request

Comments

@pontaoski
Copy link

Hi, I noticed a lack of i18n in kanidm and @Firstyear pointed me to open an issue here for conversation

My usual toolchain for introducing i18n to projects that haven't had them yet (like for instance https://github.com/Pryaxis/TShock/ or https://github.com/BlueMoonVineyard/BreweryNG) is gettext (or other .po-consuming system) + crowdin (propietary) or weblate (foss) for translation management

I'n not the most familiar with the situation of things in Rust, so i'll be doing some investigation on that; firstyear mentioned no non-rust dependencies

@pontaoski
Copy link
Author

after doing some cursory browsing through the ecosystem for i18n systems that meet the following criteria:

  • native rust, not ffi bindings to a separate lib
  • has seen signs of life within the past year
  • use a format supported by at least Crowdin and Weblate

i have singled out the following crates/projects:

  • https://github.com/corebreaker/poreader
    poreader is just a pofile format reader and would need additional scaffolding on kanidm's part to turn it into a operational i18n system
    but using the standard gettext format gets you a wide array of compatibility with tooling of all sorts, as well as editing tools that translators will be bringing themselves to contribute
    the gettext workflow is basically
    • code authors write inline strings keyed by i18n!("this is the source string: {}", 1 + 2); (this is called key-by-source where the source strings themselves are found in the code and serve as the key in the translation map)
    • an external tool "extracts" these source strings into a template .po file (or files if you want to split i18n per "components" such as web vs cli)
    • the template files are "forked" into language files, which translators edit and which external tooling keeps up to date
  • https://github.com/projectfluent/fluent-rs
    from what i can tell, this is The Rust-Native option that's 100% crab approved or something
    i don't have much experience working with it, but at a glance:
    • it's an explicit key system, where code authors write the source string in an external file foo-bar = this is the source string: {$number} and then in code, they write something like i18n("foo-bar", 1 + 2);
    • instead of separate tooling to maintain template files, code authors just edit an explicit source file
    • i'm not sure what the merging workflow looks like? if y'all went with a translation management platform like crowdin/weblate they'd probably handle it for you

@yaleman yaleman added the enhancement New feature or request label Sep 12, 2023
@yaleman
Copy link
Member

yaleman commented Sep 12, 2023

Thanks for raising this @pontaoski, it's good to know that there's genuine interest!

We should decide on a framework for this before starting #1984 so that we can do the i18n while rewriting the messages.

@Firstyear
Copy link
Member

Well we may not need to delay #1984 on this, it just means we don't use thiserror/anyhow opting for messages to be added later. Server wise the log messages would be hard to i18n. I think for the moment is is focused on the ui elements.

Regarding the options here, poreader appears to be quite old, possibly abandoned.

Fluent however, appears to be sponsored by mozilla and is much larger and healthier as an ecosystem, so it may be better to investigate this as an option.

@pontaoski
Copy link
Author

pontaoski commented Sep 12, 2023

In terms of "rust projects" Fluent is easily the healthiest, but in terms of "i18n formats" it's on shakier ground, as it's a very new format without the vast tooling support offered by older formats like Gettext. A cursory attempt of loading ftl files from Firefox into Crowdin and Weblate doesn't look very promising. Mozilla's own Pontoon seems to support it, but that would require hosting an instance specifically for kanidm since AFAIK nobody is sponsoring a free instance for FLOSS tools in general. There's nothing wrong with a plaintext-only workflow, but it would substantially increase the barrier to entry for translators without a firm grasp of git, especially with a format not exactly well-supported by desktop translation editing tools, and with a format that seems very keen on the DSL aspects of it.

@ponte-vecchio
Copy link

On the topic of suggestions, tr may be of interest. I've used it for localising paru in the past. Latest commit was July this year so it seems to tick the active box.

It works similarly to the two suggestions above, in that

  1. Annotate the strings in your source code with the write macro/functions;
  2. Run the xtr programme over the crate to extract the string in a .pot file; then
  3. Use the gettext tools to merge, translate, and generate the .mo files.

@pontaoski
Copy link
Author

That depends on gettext-rs which just calls into the non-rust gettext AFAIK

@Firstyear
Copy link
Member

That's fine, so long as there is a rust-binding that is well maintained. We aren't going to throw in something like Go or C here, but if there is gettext-rs that works, then we can use that as a possible option.

@pontaoski
Copy link
Author

Oh, I was under the impression you didn’t want to introduce a non-Rust dependency. In that case, gettext-rs would be my top suggestion for being literally just Gettext.

@pontaoski
Copy link
Author

... oh right, this has a web UI which prolly wants a solution that can handle specifiying language through any method other than environment variables :)

in that case, Fluent time?

@Firstyear
Copy link
Member

Yeah, that might be best if it supports web. We need to look deeper into it.

@pontaoski pontaoski linked a pull request Sep 13, 2023 that will close this issue
6 tasks
@tumbl3w33d
Copy link

Thank you for your effort here @pontaoski . Let me do the deutsch for you once you got something available to be translated. I can handle whatever format, I guess (would be cool if a text editor is sufficient). I've recently used python's babel in my project.

@Firstyear
Copy link
Member

I think to start with we focus on the webui and get experience there before we go into the cli or other parts of the codebase. Is it possible to have the translations loaded from different files that we can fetch at runtime? Or do they need to be "built in" at compile time?

@Firstyear
Copy link
Member

also as an aside, I think the default language fallback should be en-AU (not en-US). I think that's reasonable today since the current translation is already en-AU.

@pontaoski
Copy link
Author

these sound like comments for the implementation pull request

@ExplodingDragon
Copy link

With the recent release of 1.2.0 , are there any new developments on this issue? Maybe something like Gitea. create a project in Crowdin and use bot to auto-sync the translations ?

@Firstyear
Copy link
Member

No progress since, we want to rework our webui for now to better prepare for this.

@yaleman
Copy link
Member

yaleman commented May 14, 2024

And Crowdin looks pretty expensive for any non-trivial use 😨

@ExplodingDragon
Copy link

ExplodingDragon commented May 14, 2024

And Crowdin looks pretty expensive for any non-trivial use 😨

@yaleman This is not a problem for kanidm, she is an open source project (:

图片

@yaleman
Copy link
Member

yaleman commented May 14, 2024

60k words adds up quickly when it's target-language * words... but I guess if it's easy to move from them to someone else that might work. I'd be worried if we built a big dependency on a cloud service that ends up trying to charge someone money.

@Firstyear
Copy link
Member

I'd rather not outsource the work anyway since it's unreliable if it will continue in future. We need something in house we can manage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 📋 Backlog
Development

Successfully merging a pull request may close this issue.

6 participants