Hey all, I want to present to you my current solut...
# compose
r
Hey all, I want to present to you my current solution to the whole translations workflow, which I think solves most of the issues I have seen with translations/localizations in the industry - and I am looking for feedback. It is as simple as: 1. create a Google Sheets spreadsheet with multiple sheets for different groups of translations, and add the language columns and keys and the English translation 2. the content can be edited by non-technical people, and can include formatting like
This includes ${arg1}, ${arg2} and ${arg3}.
3. let Gemini translate into other languages 4. in the IDE, run a script which downloads the sheet and generates references such as
LangStrings.errors.generic
and functions for formatted content, such as
LangStrings.messages.someFormattedMsg(arg1: String, arg2: String, arg3: String)
5. composition locals and a few helper functions make it easy to reference the translations in Compose:
Text( LangStrings.cta.someMessage())
Code samples in thread. My goals: • allow non-devs to modify the translations easily • have an automatic step to sync the translations with the source of truth (spreadsheets) • generate references of type
StrKey
so that a translatable string can be referred to before we know the locale • generate type-safe formatting functions for translations with arguments (so far it only accepts string args, but it could be extended to typed args)
👍 1
Spreadsheet example:
Generated refs:
Generated functions for strings with arguments:
Copy code
public fun inviteCompanyFormatted(
      locale: AppLocale,
      USER_EMAIL: String,
      USER_FIRST_AND_LAST_NAME: String,
      COMPANY_NAME: String,
      URL: String,
    ): String = _inviteCompany.resolve(locale).formattedWithNamed(listOf("USER_EMAIL" to USER_EMAIL, "USER_FIRST_AND_LAST_NAME" to USER_FIRST_AND_LAST_NAME, "COMPANY_NAME" to COMPANY_NAME, "URL" to URL))
Composable helpers:
Copy code
@Composable
operator fun StrKey.invoke(vararg args: Any): String {
    val locale = LocalLocale.current
    val argsList = args.toList()
    return TranslationUtil.resolve(this, locale).formattedWith(argsList)
}

@Composable
operator fun StrKey.invoke(): String {
    val locale = LocalLocale.current
    return TranslationUtil.resolve(this, locale)
}
Generated translations:
Downsides: • currently the generated strings go in a single large hashmap. It may not be the best solution memory-efficiency-wise. • there's no IDE-built-in translations editor, so you need to either manually edit these mappings, or edit the spreadsheet and re-generate • no support (yet) for advanced entries such as plurals, lists etc.
t
Have you taken a look at https://tolgee.io/
thank you color 1
Should solve most of your issues and allows for ai translations as well as far as I can remember
g
Take a look at Accent https://www.accent.reviews/
thank you color 1