General module to support templating, gender and plural/singular definition…

Question

Some of you asked me how to extend the GlobalTranslations module to support:

  • templating
  • gender
  • plural/singular

Answer

This answer complements the one I published on March 27th, 2019 (see this link), therefore I will not re-explain everything (please refer to that post for further details on the GlobalTranslations module).

The full source code of this new solution (together with a full sample) can be found on GitHub.

Extension of the GlobalTanslations class

As previously explained, the GlobalTanslations class is implemented as a Singleton and accessible via the allTranslations global variable.

The API to get the translations has now been extended as follows:

String text(
    String key,
    {
        Map<String, dynamic> values,
        num plural,
        GlobalTranslationsGender gender,
    }
)

Usage

Basic

String myText = allTranslations.text('demoPage.title');

Returns the string, in the current language, found in the corresponding ‘/assets/locale/locale_{currentLanguage}.json’ file.

Templating

We may now define a template.

Suppose the ‘locale.json’ file is defined as follows:

{
    "demoPage": {
        "template": "My name is {{name}} and I live in {{country}}"
    }
}

You may now replace the values in the template as follows:

String myText = allTranslations.text(
    'demoPage.template',
    values: {
        'name': 'Didier',
        'country': 'Belgium'
    },
);

The outcome will become: “My name is Didier and I live in Belgium”.

Plural

We may now define different strings or templates, based on a “plural” argument.

Suppose the ‘locale.json’ file is defined as follows:

{
    "demoPage": {
        "plural_test": {
            "=0": "I have no children",
            "=1": "I have one child",
            ">1": "I have several children"
        }
    }
}

You may now obtain the string/template that corresponds to the ‘plural’ argument as follows:

String myText = allTranslations.text(
    'demoPage.plural_test',
    plural: 1,
);

Based on the “plural” argument, the routine will fetch the corresponding string, following the rule:

  • if ‘plural’ == 0, fetch the ‘=0’ corresponding string/template
  • if ‘plural’ == 1, fetch the ‘=1’ corresponding string/template
  • if ‘plural’ > 1, fetch the ‘>1’ corresponding string/template

In our example, as plural==1, the outcome will be: ‘I have one child’

Gender

We may also define the string/template to be used based on a gender argument.

This gender argument corresponds to an enum GlobalTranslationsGender.

Suppose the ‘locale.json’ file is defined as follows:

{
    "demoPage": {
        "gender_test": {
            "male": "I am a man",
            "female": "I am a woman",
            "other": "Not specified"
        }
    }
}

You may now obtain the string/template that corresponds to the ‘gender’ argument as follows:

String myText = allTranslations.text(
    'demoPage.gender_test',
    gender: GlobalTranslationsGender.male,
);

The outcome of this will be: ‘I am a man’ since gender == GlobalTranslationsGender.male.

Note

You can combine plural and values or gender and values BUT YOU MAY NOT have both plural and gender defined at the same time.

Example:

{
    "demoPage": {
        "gender_template": {
            "male": "I am a man. Height: {{size}}",
            "female": "I am a woman. Height: {{size}}",
            "other": "Not specified"
        }
    }
}

You may now replace the values in the template as follows:

String myText = allTranslations.text(
    'demoPage.gender_template',
    gender: GlobalTranslationsGender.male,
    values: {
        "size": "1.80m"
    },
);

Conclusions

Simple extension of the module which might be very useful, I hope.