Jesway / flutter_translate

Flutter Translate is a fully featured localization / internationalization (i18n) library for Flutter.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ability to customise argument escape characters

MichaelMarner opened this issue · comments

This package uses single braces to escape arguments in translation strings:

{
  "message": "Hello {name}!"
}

Most other similar translation libraries (eg ngx-translate, i18next) use double braces to escape:

{
  "message": "Hello {{name}}!"
}

We are using flutter_translate in our Flutter app, and ngx-translate in our Web app. We would really like to consolidate our translation strings so they are shared between both projects, as this will help ensure messages are consistent across platforms and reduce costs of translating to other languages.

I'm wondering if a good approach would be to allow customising the argument escape characters, so we could use double-braces in our project. For backwards compatibility, we would default to the current single brace behaviour. Perhaps set the escape characters as optional parameters to Localization.load:

class Localization
{
    static void load(Map<String, dynamic> translations, {openingEscapeString = '{', closingEscapeString = '}'})
    {
        instance._translations = translations;
        instance._openingEscapeString = openingEscapeString;
        instance._closingEscapeString = closingEscapeString;
    }
}

I'm happy to do the work to support this, would just like some feedback on the approach.

Cheers!

Hi Michael, I suppose we can add double braces as a configurable option, but we have to keep it simple.

I think the best way would be to add a useDoubleBraces property to the localization delegate create method, which can be configured on startup.

We can then pass this value to the localization object through an initializer instead of the load method since the purpose of this method is to only load localizations.

So the reason I suggested having the escape characters as parameters to load is so the meaning is something like:

"here are these translation strings, which use { and } as escape characters"

In other words, the escape characters are a property of the localisation strings, not a global configuration property on the library, and would allow for loading more translations at a later time, etc.

I'm also not fussed, so I'm happy to make it a parameter to create if that's what you'd prefer. Perhaps though use an enum for the type of escape characters instead of a boolean flag for double would be cleaner though?

Cheers

I have a similar need. The translation file is coming from some translation service and is shared with other native Android apps. So, I need to apply some transformations on the texts, e.g. android localization uses %s in values and other things like html formatting does not work well in Flutter.

I made a local fork of flutter-translate and extended LocalizationDelegate.create(..) that takes post-processors for keys and plurals. I can contribute it in a PR if you'd be interesting to integrate it.

Here is an example of the post processing I need use:

  static String _processString(String value, String key, String arg) {
    return value
        .replaceAll('\\\'', '\'')
        .replaceAll('\\n', '\n')
        .replaceAllMapped(RegExp(r'^\"(.*)\"$'), (m) => m[1]!)
        .replaceAllMapped(RegExp(r'(.*):$'), (m) => m[1]!)
        .replaceAll('<b>', '')
        .replaceAll('</b>', '')
        .replaceAll('\\"', '"')
        .replaceAll('%s', '{s}')
        .replaceAll('%.2f', '{s}')
        .replaceAll('%.4f', '{s}')
        .replaceAll(r'%1$s', '{s1}')
        .replaceAll(r'%2$s', '{s2}')
        .replaceAll(r'%3$s', '{s3}')
        .replaceAll(r'%4$s', '{s4}')
        .replaceAll(key, arg);
  }

  static String _processPlural(String value, String key, String arg) {
    return value
        .replaceAll('%s', '{{value}}')
        .replaceAll(key, arg);
  }