Browsed by
Category: PluralNet

PluralNet: Pluralization for your .Net application

PluralNet: Pluralization for your .Net application

Intro: http://www.rudyhuyn.com/blog/2016/09/28/pluralization-the-missing-part-of-net/

I created a new library named PluralNet, managing plural forms for you, very easy to use and compatible with RESW files as well as RESX files.

Contrary to other ios/android libraries, this one will also manage decimal numbers, the code is a little more complex but very useful.

How to use it?

A Nuget package named PluralNet is available, so install it from Visual Studio or using the following command line:

Install-Package PluralNet

How to manage plural forms in your resource files

It was very important to not break the resw or resx format, so, instead of one entry in your resource file, you Will need to create one entry for each plural form used by the language (ONE, OTHER, FEW?, MANY?, ZERO?, TWO?).

To make it simple and compatible with all localization tools, I used the same terminology than unicode  (also used by Android and iOS):

English (2 plural forms):

capture

Polish (4 plural forms)

capture

In order to use the correct plural rules, the library needs to know the language used by the app and not by the system (for example a polish phone displaying an english application need to use the english rule instead of polish).

To do that, you need to add an extra entry in your RESW file (if not already done by Visual Studio):

capture

The library will use this value to select the correct rules.

Manage pluralization code-behind

If you use RESW:

To make it easy to use, I created a extension to ResourceLoader, so instead of

ResourceLoader.GetForCurrentView().GetString("TimeStampDay");

you must use:

ResourceLoader.GetForCurrentView().GetPlural("TimeStampDay", <NUMBER>);

And optionally use string.Format(…) if your string supports formatting.

If you use RESX:

AppResources.TimeStampDay;

you must use:

AppResources.ResourceManager.GetPlural("TimeStampDay", <NUMBER>);

And optionally use string.Format(…) if your string supports formatting.

XAML

To use pluralization XAML-side, you can use the converter PluralConverter:


<TextBlock Text="{x:Bind NumberDays, Converter={StaticResource PluralConverter}, ConverterParameter=TimeStampDay}" />

If your localized string uses formatting, {0} will be automatically replaced by the number.

You can also create your own Converter if you want a different behavior.

Platforms

The library supports:

  • Silverlight 5
  • Windows Phone Silverlight 8.0
  • Windows 8 and 8.1 WinRT apps
  • Windows Phone 8.1 WinPRT apps
  • UWP
  • ASP.Net Core
  • .Net Desktop apps (winform, wpf, etc…)
  • Xamarin Android and iOS

Language supported

Afrikaans, Akan, Albanian, Amharic, Arabic, Armenian, Assamese, Asturian, Asu, Azerbaijani, Bambara, Basque, Belarusian, Bemba, Bena, Bengali, Bihari, Bodo, Bosnian, Breton, Bulgarian, Burmese, Catalan, Central Atlas Tamazight, Central Kurdish, Chechen, Cherokee, Chiga, Chinese, Colognian, Cornish, Croatian, Czech, Danish, Divehi, Dutch, Dzongkha, English, Esperanto, Estonian, European Portuguese, Ewe, Faroese, Filipino, Finnish, French, Friulian, Fulah, Galician, Ganda, Georgian, German, Greek, Gujarati, Gun, Hausa, Hawaiian, Hebrew, Hindi, Hungarian, Icelandic, Igbo, Inari Sami, Indonesian, Inuktitut, Irish, Italian, Japanese, Javanese, Jju, Kabuverdianu, Kabyle, Kako, Kalaallisut, Kannada, Kashmiri, Kazakh, Khmer, Korean, Koyraboro Senni, Kurdish, Kyrgyz, Lakota, Langi, Lao, Latvian, Lingala, Lithuanian, Lojban, Lower Sorbian, Lule Sami, Luxembourgish, Macedonian, Machame, Makonde, Malagasy, Malay, Malayalam, Maltese, Manx, Marathi, Masai, Metaʼ, Moldavian, Mongolian, Nahuatl, Nama, Nepali, Ngiemboon, Ngomba, North Ndebele, Northern Sami, Northern Sotho, Norwegian, Norwegian Bokmål, Norwegian Nynorsk, Nyanja, Nyankole, N’Ko, Oriya, Oromo, Ossetic, Papiamento, Pashto, Persian, Polish, Portuguese, Prussian, Punjabi, Romanian, Romansh, Rombo, Root, Russian, Rwa, Saho, Sakha, Samburu, Sami languages [Other], Sango, Scottish Gaelic, Sena, Serbian, Serbo-Croatian, Shambala, Shona, Sichuan Yi, Sinhala, Skolt Sami, Slovak, Slovenian, Soga, Somali, South Ndebele, Southern Kurdish, Southern Sami, Southern Sotho, Spanish, Swahili, Swati, Swedish, Swiss German, Syriac, Tachelhit, Tagalog, Tamil, Telugu, Teso, Thai, Tibetan, Tigre, Tigrinya, Tongan, Tsonga, Tswana, Turkish, Turkmen, Tyap, Ukrainian, Upper Sorbian, Urdu, Uyghur, Uzbek, Venda, Vietnamese, Volapük, Vunjo, Walloon, Walser, Welsh, Western Frisian, Wolof, Xhosa, Yiddish, Yoruba, Zulu

Source code

The source code is available under MIT license:

https://github.com/rudyhuyn/PluralNet

How to help?

If you detect an issue, want to add a language, don’t hesitate to submit a push request on github!

 

 

Pluralization: the missing part of .Net

Pluralization: the missing part of .Net

Plural forms are a lot more complex than we think, there is no generic rules to manage plurals, each languages have their specific rules. A lazy way is to ignore them:

3 item(s) in your cart

As a designer, I hate that, it’s laziness.

So a lot of applications write a code similar to this one:

if(numberOfItem == 1)
   return SINGULAR;
else
   return PLURAL;

It’s better but still wrong, except if you only support english, did you know that this rule is incorrect in French for example?

Contrary to English, the number 0 is singular as well as all numbers between 0 and 2 (excluded) so the correct code for french is:

if(number<2)
   return SINGULAR;
else
   return PLURAL;

Let take an other language, Hindi for instance. In Hindi, 0.3 is singular (plural in english, singular in french) whereas 1.8 is plural (plural in english, singular in french)

One more time, rules are different, here is the algorithm for Hindi:

if(number >= 0 && number <= 1)
   return SINGULAR;
else
   return PLURAL;

More than 2 forms

So rules are different between languages, but not all languages are binary, for some languages there is more than 2 plural forms, Czech has a third form for example:


if(number >= 2 && number <= 4)
   return FEW;
else if(number ==1)
   return SINGULAR;
else
   return PLURAL;

But there is more complicated, let’s take a look to Polish:

if ((n % 10).IsBetween(2, 4) && !(n % 100).IsBetween(12, 14))
{
   return FEW;
}
if (n != 1 && (n % 10).IsBetween(0, 1) ||
(n % 10).IsBetween(5, 9) ||
(n % 100).IsBetween(12, 14))
{
   return MANY;
}
if (n == 1)
{
   return ONE;
}
return OTHER;

4 different forms and some very complex rules, a real challenge but wait, there is more complicated.

Decimal numbers

We need also to manage decimal numbers. For a lot of readers, the number 98.41 and 98.45 will have the same plural form, but not for everyone, some languages use the last number of the fractional part to make a choice, 98.41 can be singular for some languages (because ending with 1) contrary to 98.45 (because ending with a 5).

Moreover, some languages make a distinction between 1 (singular) and and 1.0 (plural)…

The rules

Unicode released a very interesting page to understand the differences between all languages, it was one of my main sources to create this library:

http://www.unicode.org/cldr/charts/25/supplemental/language_plural_rules.html

So how it works with .Net?

This is the issue, contrary to other platforms (ios, android. etc..), .Net doesn’t manage pluralization out-of-the-box and no third-party libraries are available.

Solution

I created a new library named PluralNet, managing almost all existing languages (including regional languages), very easy to use and compatible with RESW files as well as RESX files.

More information here: http://www.rudyhuyn.com/blog/2016/09/28/pluralnet