Due to its deceptive simplicity, pluralization can be a somewhat overlooked element when handling strings in programs. If your application only speaks one language, say English, pluralizing is oftentimes as simple as suffixing its nouns with an “s” or “es”. But, if you rightfully chose to localize/internationalize your app in multiple locales, the languages and their own pluralization rules and forms might make the once ignorable task of pluralization a bit of a challenge to overcome!
Be it for a front-end or back-end language, coders use different methods and tools to perform pluralization. So, without further ado, let’s explore a few programming languages and figure out how each of them tackles pluralization, shall we?
We will cover the following in this article:
- A step-by-step guide to creating a Vanilla JavaScript app and performing string pluralization in it.
- Basic pluralization using hardcoded JS functions.
- Using the
Pluralize
JS library to pluralize English strings. - Performing pluralization for multiple locales utilizing the
Numerous
JS library. - A walkthrough on setting up a simple Java project and pluralizing strings in it.
- Utilizing the
ICU MessageFormat
class for Java pluralization. - Placeholder usage through the JavaScript
Pluralize
library. - Using
ICU MessageFormat
arguments as placeholders when pluralizing in a Java application.
Assumptions
Basic knowledge of:
- JavaScript
- Java
Prerequisites
A local environment set up with:
- JavaScript-supported IDE.
- JavaScript-enabled browser.
- Java-supported IDE.
- JDK 5 or higher.
- Maven 3.3 or higher.
Environment
I will be using the following environment for my development purposes:
- WebStorm 2019.1 Build #WS-191.7141.49
- Firefox 94.0 (64-bit)
- IntelliJ IDEA 2019.1.2 Build #IU-191.7141.44
- JDK 8u301
- Maven 3.3.9
JavaScript pluralization
As our first language, let’s take a look at how we can pluralize strings in JavaScript.
The source code is available on GitHub.
Basic JavaScript project setup
Time to count some apples! First up, let us create a simple JavaScript project where we’ll later place our pluralization examples.
Let’s open our JavaScript IDE and create a new project named “PluralizationJS” inside a directory of an equal name.
Secondly, we’ll create an “index.html” file inside our PluralizationJS
project to act as our project’s default page. Don’t forget to fill it with some initial HTML elements, like so:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>PluralizationJS</title> </head> <body> </body> </html>
Note: You’re in luck if using WebStorm, since typing “!” and pressing Tab will generate the entire code in one go!
Thirdly, let’s populate our “index.html” file’s HTML <body>
with some skeleton HTML elements:
<table> <tr> <td id="apple_count_zero"> </td> </tr> <tr> <td id="apple_count_one"> </td> </tr> <tr> <td id="apple_count_few"> </td> </tr> <tr> <td id="apple_count_many"> </td> </tr> </table>
As you might have already guessed, we’ll learn ways to fill this table with correctly populated apple counts in the upcoming sections.
Child’s play pluralization
Before touching on any libraries, how about we get to grips with JavaScript pluralization in the simplest way imaginable? Let’s use our good old if
/else
functions to portray a count of apples that is correctly pluralized according to English pluralization rules.
Firstly, we’ll head over to our PluralizationJS
project’s “index.html” file and place a function inside its <head>
tag:
. <script> function getAppleCount(count) { // 1 if (count === 1) { // 2 return "1 apple"; } else if (count === 0 || count > 1) { // 3 return count + " apples"; } else { // 4 return "That's surely an invalid count of apples!"; } } </script>
- Create a
getAppleCount
function that accepts acount
parameter. - In the case that the count is 1, return a string with a value of “1 apple”.
- If the count is 0 or greater than 1, return a string concatenating the count with an “apples” string.
- If no match was found for the provided count, return a string informing of the invalid input.
Secondly, let’s add another <script>
in the “index.html” file’s <body>
tag:
. <script> document.getElementById("apple_count_zero").innerHTML = getAppleCount(0); document.getElementById("apple_count_one").innerHTML = getAppleCount(1); document.getElementById("apple_count_few").innerHTML = getAppleCount(2); document.getElementById("apple_count_many").innerHTML = getAppleCount(5); </script>
Important note: Make sure to place this script below the previously placed skeleton HTML table. This is so that by the time the JavaScript code looks for table elements by ID, they will already be rendered and available.
This script calls the getAppleCount
function passing different counts and sets the relevant table element’s value to the function’s return value.
Test it out
Running our PluralizationJS
application should show the properly pluralized apple counts:
Time to use a 3rd-party library
The previous method was easy enough—but, what if we needed to count oranges instead of apples? We’d either need to change all the strings in the getAppleCount
function to represent orange counts or code a new function altogether. What if it’s not just apples and oranges but a thousand more types of fruit that we need to count?
Thankfully, there are far more efficient and far less messy approaches to counting the fruit—or in other words, pluralizing the strings—in our JavaScript applications.
Use Pluralize library
The Pluralize JavaScript library lets us pluralize strings in the English locale quite easily. Why don’t we find out how to set it up for our PluralizationJS
app?
First things first, download the Pluralize library as a ZIP file from GitHub. Secondly, let’s extract this ZIP file and place the pluralize.js
file inside it at the root of our PluralizationJS
project directory:
Thirdly, let’s not forget to import this library to our project’s “index.html” file by placing this line inside its <head>
tag:
https://gist.github.com/nirm2009/b29b4c661a769e2ac8b5f830c2c82938
Fourthly, let’s add a new getAppleCountUsingPluralizeLib
function inside the <head>
tag of our PluralizationJS
project’s “index.html” file:
. <script> function getAppleCountUsingPluralizeLib(count) { // 1 if (count >= 0) { // 2 return pluralize("apple", count, true); // 3 } else { // 4 return "That's surely an invalid count of apples!"; } } </script>
- Create a
getAppleCountUsingPluralizeLib
function that accepts acount
parameter. - Check if the
count
value is greater than or equal to zero—that is to say, a countable quantity of apples. - Call the
pluralize
method from thePluralize
library, successively passing in:- the word to pluralize in its singular form, which in our case would be “apple”.
- the count of items to base the pluralization on—here we’ll directly pass the
getAppleCountUsingPluralizeLib
function’scount
argument. - a boolean informing the
pluralize
method whether to prefix the result with the item count or not.
- If the condition in step 2 isn’t met, return a string informing of the invalid input.
Finally, we’ll make a few changes to our <script>
inside the <body>
, which changes the HTML table values. This time around, let us call our getAppleCountUsingPluralizeLib
function to receive values to set on the HTML table elements:
. <script> document.getElementById("apple_count_zero").innerHTML = getAppleCountUsingPluralizeLib(0); document.getElementById("apple_count_one").innerHTML = getAppleCountUsingPluralizeLib(1); document.getElementById("apple_count_few").innerHTML = getAppleCountUsingPluralizeLib(2); document.getElementById("apple_count_many").innerHTML = getAppleCountUsingPluralizeLib(5); </script>
Test it out
Let’s run our PluralizationJS
application to see if everything works as expected:
As we can see, the apple counts are nicely pluralized. But don’t forget! This time we didn’t manually code the pluralization logic. We only supplied the word “apple” in its singular form to the Pluralize
library, along with the counts, and the library worked its magic to conveniently provide us with the words in their properly pluralized forms.
Enter Numerous library
Although the Pluralize
library was easy to set up and use, there’s a catch, and a quite big one in fact! It’s designed to only work for the English language. Hence, if we need our JavaScript application to pluralize its string values in multiple locales, we’re out of luck with Pluralize
.
When it comes to pluralizing values in several locales, a handy Numerous JS library comes to the rescue. Let’s see how we can use it.
Firstly, let’s add a few HTML buttons to our PluralizationJS
project’s “index.html” file <body>
:
. <button id="lang_choice_en">Pluralize in English</button> <button id="lang_choice_ru">Pluralize in Russian</button>
Later on, we’ll set up event listeners to call the Numerous
library once they are clicked.
Set up Numerous library
Next, it’s time to download the Numerous
library.
Since the original library is focused on functioning and setting up through Node and we plan to use plain old Vanilla JavaScript in this guide, we opted to create a fork of the Numerous
library. This GitHub fork comments out a few Node-related codes in the Numerous
library and replaces them with Vanilla JS code letting the pluralization in this guide work using Vanilla JavaScript.
Let’s download the ZIP file of the Numerous
library fork and extract it to the root folder of our PluralizationJS
project:
Important Note: Note that only the code used in this guide is fittingly modified in this Numerous
fork. Hence, avoid using this fork for your production-level code and resort to the original Numerous
library.
Use Numerous library
Given that there’ll be a considerable amount of code and JavaScript module imports, it’d be cleaner for us to write all Numerous
library-related code as a separate module. Therefore, as our third step, let’s create a “numerous_pluralization.js” file inside our PluralizationJS
project’s root folder with some initial imports:
import * as numerous from "./numerous-master/lib/numerous.js"; import enLocale from "./numerous-master/locales/en.js"; import ruLocale from "./numerous-master/locales/ru.js";
Numerous
asks us to load all the locales we plan to use before we use its pluralization features. So, we’ll go ahead and register the English and Russian locales inside our numerous_pluralization
module:
. numerous.registerLocale(enLocale); numerous.registerLocale(ruLocale);
The library uses CLDR and is hence aware of CLDR plural rules, but it relies on us to provide all the plural variants, unlike the Pluralize
library. This being the case, let’s add a const
to our numerous_pluralization
module to hold localized plural form variants for a count of apples:
. const pluralFormVariants = { en: { one: 'apple', other: 'apples' }, ru: { one: 'яблоко', few: 'яблока', many: 'яблок' } };
Next up, let’s add a pluralizeUsingNumerous
function to the numerous_pluralization
module:
. function pluralizeUsingNumerous(langChoice) { // 1 document.getElementById("apple_count_zero").innerHTML = 0 + " " + numerous.pluralize(langChoice, 0, pluralFormVariants[langChoice]); // 2 document.getElementById("apple_count_one").innerHTML = 1 + " " + numerous.pluralize(langChoice, 1, pluralFormVariants[langChoice]); document.getElementById("apple_count_few").innerHTML = 2 + " " + numerous.pluralize(langChoice, 2, pluralFormVariants[langChoice]); document.getElementById("apple_count_many").innerHTML = 5 + " " + numerous.pluralize(langChoice, 5, pluralFormVariants[langChoice]); }
- Create a
pluralizeUsingNumerous
function that accepts alangChoice
parameter. - Call the
numerous.pluralize
function, consecutively passing in thelangChoice
argument, an apple count of 0, and an extracted plural form variant object for the givenlangChoice
from thepluralFormVariants
const. Set the returned value on the HTML element with an ID of “apple_count_zero”.
Similarly, call the numerous.pluralize
function for the rest of the plural form variants and set the returned value on the appropriate HTML elements.
Then, let us add event listeners in our numerous_pluralization
module for the HTML buttons we placed in the previous section:
. document.getElementById('lang_choice_en').addEventListener('click', function() { pluralizeUsingNumerous("en"); // 1 }); document.getElementById('lang_choice_ru').addEventListener('click', function() { pluralizeUsingNumerous("ru"); // 2 });
- Call the
pluralizeUsingNumerous
function with an “en” argument when the element with ID “lang_choice_en” is clicked. - Call the
pluralizeUsingNumerous
function with an “ru” argument when the element with ID “lang_choice_ru” is clicked.
Finally, let’s not forget to import this numerous_pluralization
module into our PluralizationJS
project’s index file. We can perform this import simply by adding the following line in the <head>
tag of the “index.html” file:
https://gist.github.com/nirm2009/87d9dbe2e88196695747e1c4f763247a
Test it out
Running our PluralizationJS
application lets us retrieve a pluralized apple count in the English locale and also in the Russian locale:
In English:
In Russian:
Java pluralization
Much like front-end programming languages, their counterparts, back-end languages, require methods for string pluralization all the same. So, let’s explore how Java tackles string pluralization.
The source code is available on GitHub.
Basic Java project setup
First off, let’s create a simple Java application to use as the stage for trying out our pluralizations. For this, we’ll open up our favorite Java IDE and create a PluralizationJava
Maven project inside it with this configuration:
GroupId: com.lokalise ArtifactId: pluralization-java Version: 1.0-SNAPSHOT
Note: These configurations are placed as guidelines only. Hence, feel free to set them up as you prefer.
Secondly, let us create a Main
class holding a main method inside our PluralizationJava
project’s src/main/java
folder:
. public class Main { public static void main(String[] args) {} }
Pluralization with ICU
The native string pluralization method Java currently provides surely leaves a lot to be desired. As we covered in our Java internationalization basics article, Java asks us to resort to the ChoiceFormat class for pluralization. This method theoretically works but ends up requiring hundreds of String and double arrays, making our application quite cumbersome to modify and manage.
Exploring more practical ways of pluralization, the decades-matured ICU and its Java variant, the ICU4J library, prove to be our best bet! Why don’t we set up this ICU4J
library in our PluralizationJava
project and see for ourselves how mature it actually is?
Set up ICU4J library
Let us simply head over to our PluralizationJava
project’s pom.xml
file and add the latest ICU4J
library as a dependency:
. <dependencies> <dependency> <groupId>com.ibm.icu</groupId> <artifactId>icu4j</artifactId> <version>70.1</version> </dependency> </dependencies>
Note: The mentioned ICU4J library version was simply the latest one available in the Maven repository at the time of writing and is therefore subject to change over time.
Enter ICU MessageFormat
Although Java natively brings out a MessageFormat class, it unfortunately lacks any sort of pluralization support. But, admiringly, ICU supplies its own MessageFormat class which knows how to handle plurals. Moreover, ICU’s MessageFormat
inherits from the native java.text.Format class consequently exposing all its methods to the ICU MessageFormat
itself.
MessageFormat(String pattern, ULocale locale)
constructor explanation
We will use this MessageFormat
constructor to initialize MessageFormat
objects in the coming sections. This is because it allows a ULocale input, letting us define the locale we plan to localize our string in.
MessageFormat
expects us to provide a pattern string with a specific syntax. Since we’re planning to pluralize our strings, the pattern syntax we must attend to would be:
pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
The first parameter, argNameOrNumber
, is where we should pass in the quantity or count for MessageFormat
to pluralize on. This parameter accepts one of two options:
- A map argument name that holds the count as its value.
- An array index that holds the count.
This map or array which contains the particular count argument or index is passed in when calling the MessageFormat
object’s format
method.
The second parameter, plural
, simply informs MessageFormat
that this is a plural pattern.
The third parameter, pluralStyle
, obtains all the data for the plural forms according to the pluralStyle
syntax in PluralFormat.
Pluralize with MessageFormat
Firstly, let’s introduce a new static
method to our PluralizationJava
project’s Main
class:
private static void pluralizeUsingMessageFormat() { // 1 MessageFormat pluralMessageFormat = new MessageFormat( // 2 "{quantity, plural, " + "=0{There are no apples.}" + "=1{There is one apple.}" + "other{There are # apples.}" + "}", ULocale.ENGLISH); // 3 Map patternArgs = new HashMap(); // 4 patternArgs.put("quantity", 0); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 1); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 2); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 5); System.out.println(pluralMessageFormat.format(patternArgs)); }
- Create a
pluralizeUsingMessageFormat
method. The method is kept asstatic
to allow it to be called from the main method later on. - Initialize a
MessageFormat
named “pluralMessageFormat”. As the first argument to the constructor, pass in an array holding:- a map key value of “quantity”.
- an instruction that it’s a plural pattern.
- sentences in plural forms in compliance with the PluralFormat syntax.
- For the second argument to the
MessageFormat
constructor, provide a ULocale of the English language. - Create a
HashMap
namedpatternArgs
, place different values for its “quantity” key, and call the inheritedformat
method ofpluralMessageFormat
, passing in thepatternArgs
map to it as an argument.
Secondly, let’s not forget to call this pluralizeUsingMessageFormat
method inside our PluralizationJava
project’s main method:
public static void main(String[] args) { pluralizeUsingMessageFormat(); }
Test it out
Let’s run our PluralizationJava
app and see if the ICU4J
MessageFormat
can count our apples properly!
Pluralize in French
What if we need to pluralize in another locale? With MessageFormat
, it boils down to a single MessageFormat
initialization.
Let’s head over to our pluralizeUsingMessageFormat
method and change its MessageFormat
initialization as follows:
MessageFormat pluralMessageFormat = new MessageFormat( // 1 "{quantity, plural, " + "=0{Il n'y a pas de pommes.}" + "=1{Il y a une pomme.}" + "other{Il y a # pommes.}" + "}", ULocale.FRENCH); // 2
- Initialize
pluralMessageFormat
with aMessageFormat
object holding a French plural pattern as its first argument. - Pass a ULocale of the French language for the 2nd argument.
Test it out
Running our PluralizationJava
application again shows us the correctly pluralized apple counts—but this time in French!
Load plural pattern externally
Suppose we needed our app to successfully count apples in hundreds of locales. Technically, we could write thousands of lines inside our application’s classes, but it’d only bog down the whole application, don’t you think? And, in fact, with ChoiceFormat we would have been forced to do exactly that. But, thanks to ICU MessageFormat
patterns and their serializable pattern syntaxes, we can safely place all our plural patterns for all locales inside Java properties
files and call it a day! Let’s find out how to do this, shall we?
Firstly, let’s navigate to our PluralizationJava
project’s src/main/resources
directory and add a “pattern_en.properties” file inside it:
applecount={quantity, plural, =0{There are no apples.}=1{There is one apple.}other{There are # apples.}}
Note: It’s safe to create a “resources” directory in the mentioned path if it doesn’t already exist.
Necessarily, we placed the same English plural pattern we set in the previous section as a property value this time around, along with an “applecount” property key.
Likewise, secondly, let’s add a “pattern_fr.properties” file to hold the French locale counterparts right next to the previous properties file:
applecount={quantity, plural, =0{Il n'y a pas de pommes.}=1{Il y a une pomme.}other{Il y a # pommes.}}
Thirdly, we’ll add a static method to the Main
class of our PluralizationJava
project:
private static void pluralizeWithExternalPluralPattern() { // 1 ResourceBundle resourceBundleEn = ResourceBundle.getBundle("pattern", Locale.ENGLISH); // 2 String patternEn = resourceBundleEn.getString("applecount"); // 3 MessageFormat pluralMessageFormat = new MessageFormat(patternEn, ULocale.ENGLISH); // 4 Map patternArgs = new HashMap(); // 5 patternArgs.put("quantity", 0); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 1); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 2); System.out.println(pluralMessageFormat.format(patternArgs)); patternArgs.put("quantity", 5); System.out.println(pluralMessageFormat.format(patternArgs)); }
- Add a static
pluralizeWithExternalPluralPattern
method. - Use ResourceBundle.getBundle() to retrieve the resource bundle with a base name of “pattern” and a
Locale
of English. In our case,ResourceBundle
will load the resource bundle in the “pattern_en.properties” file. Save the loaded resource bundle in a “resourceBundleEn”ResourceBundle
object. - Ask
resourceBundleEn
to get a string value for an “applecount” key from the resource bundle it’s holding. Store the received string value in a “patternEn” String object. - Initialize
pluralMessageFormat
with aMessageFormat
object holdingpatternEn
as its plural pattern and a ULocale of English. - Create a
HashMap
namedpatternArgs
, place different values for its “quantity” key, and call the inheritedformat
method ofpluralMessageFormat
, passing in thepatternArgs
map to it as an argument.
Fourthly, let’s call this pluralizeWithExternalPluralPattern
method inside our PluralizationJava
project’s main method:
public static void main(String[] args) { pluralizeWithExternalPluralPattern(); }
Test it out
That’s it! Running our PluralizationJava
app will show us the same result we achieved earlier. But don’t forget! This time the whole plural pattern was taken from an easily modifiable resource file:
Pluralize in French
Just like the last time, pluralizing in another locale requires hardly any changes to the code.
Let’s navigate to our pluralizeWithExternalPluralPattern
method and change the first few lines, like so:
private static void pluralizeWithExternalPluralPattern() { ResourceBundle resourceBundleFr = ResourceBundle.getBundle("pattern", Locale.FRENCH); // 1 String patternFr = resourceBundleFr.getString("applecount"); // 2 MessageFormat pluralMessageFormat = new MessageFormat(patternFr, ULocale.FRENCH); // 3 . . }
- Use ResourceBundle.getBundle() to get the resource bundle with a base name of “pattern” and a
Locale
of French. This time around,ResourceBundle
will load the resource bundle in the “pattern_fr.properties” file. Store the loaded resource bundle in a “resourceBundleFr”ResourceBundle
object. - Ask
resourceBundleFr
to get a string value for an “applecount” key from the resource bundle it’s holding. Store the received string value in a “patternFr” String object. - Initialize
pluralMessageFormat
with aMessageFormat
object holdingpatternFr
as its plural pattern and a ULocale of French.
Test it out
That’s all it takes! Let’s run our PluralizationJava
application to see the apple count delightfully pluralized in French:
Some pluralization extras
At this point, we have explored ways to pluralize strings in multiple languages—both front-end and back-end. How about we take things a bit further and learn a few more pluralization-related tricks while we’re at it?
Set placeholders using Pluralize
Venturing back toward the front end, let’s discover how we can use placeholders when pluralizing our PluralizationJS
application.
Firstly, we’ll head over to the “index.html” file of our PluralizationJS
project and code a new function inside its <head>
tag:
. <script> function getCountWithPlaceholdersUsingPluralizeLib(name, item, count) { // 1 if (count >= 0) { // 2 let pluralizedItemCountText = pluralize(item, count, true); // 3 return name + " had " + pluralizedItemCountText; // 4 } else { return "That's surely an invalid count!"; // 5 } } </script>
- Create a
getCountWithPlaceholdersUsingPluralizeLib
function that accepts the parameters:name
– holds a name input from the user.item
– keeps an item input that the user wishes to pluralize.count
– holds the number of items the user wishes to pluralize for their previously provided item.
- Check if the
count
value is greater than or equal to zero to avoid uncountable number inputs. - Call the
Pluralize
library’spluralize
function. As its arguments, consecutively pass initem
,count
, and a boolean indicating prefixing of the result with the item count. Save the returned pluralization result in apluralizedItemCountText
variable. - Return a string concatenating the
name
argument with the pluralized result inpluralizedItemCountText
. - If the condition in step 2 isn’t met, return a string informing of the invalid input.
Secondly, let’s add some empty HTML elements inside the <body>
tag of our project’s “index.html” file:
<table> <tr> // 1 <td><label for="name_input">Name: </label></td> <td><input type="text" id="name_input"></td> </tr> <tr> <td><label for="item_input">Item: </label></td> <td><input type="text" id="item_input"></td> </tr> <tr> <td><label for="item_count_input">Item count: </label></td> <td><input type="text" id="item_count_input"></td> <td><button id="placeholder_submit">Submit</button></td> // 2 </tr> </table> <p id="placeholder_output"></p> // 3
- Add HTML table rows to get the user inputs required by the
getCountWithPlaceholdersUsingPluralizeLib
function. - Add an HTML button with an ID of “placeholder_submit” to bind with an event handler later on.
- Put in an empty HTML paragraph element with an ID of “placeholder_output” to display the pluralization result.
Thirdly, let’s add an event handler script right below the HTML table we previously scripted:
. <script> document.getElementById("placeholder_submit").onclick = function() { // 1 let countWithPlaceholders = getCountWithPlaceholdersUsingPluralizeLib( // 2 document.getElementById('name_input').value, document.getElementById('item_input').value, +document.getElementById('item_count_input').value ); document.getElementById("placeholder_output").innerHTML = countWithPlaceholders; // 3 }; </script>
- Place a JavaScript
onclick
event handler to trigger on the click of theplaceholder_submit
button. - Call
getCountWithPlaceholdersUsingPluralizeLib
, passing the user input values for its arguments. Store the returned value in acountWithPlaceholders
variable. Notice that The 3rd argument is prefixed with a unary plus operator to convert the valuedocument.getElementById
returns into a number. - Set the value of the “placeholder_output” element to the value in
countWithPlaceholders
.
Test it out
This time we’re not restricted to apples! Let’s hypothetically count the exes Joey and Chandler had in Friends. Let’s run our PluralizationJS
application and input some values for the placeholders:
Although a die-hard Friends fan might whack us on our way home for those incorrect numbers, we’ve successfully placed placeholders while pluralizing.
MessageFormat arguments as placeholders
Moving back to the back end, ICU MessageFormat
and its arguments don’t let us down when it comes to placeholders. Let’s see how we can set up placeholders when pluralizing strings in our Java applications.
Imagine our PluralizationJava
application serves for an apple farm distributed worldwide. Assume we need to print the count of apples available on specific farms. Let’s find out how we can pass in these locations as placeholder values alongside the apple counts.
Firstly, we’ll open up our PluralizationJava
project’s Main
class and add a static method inside it:
private static void pluralizeUsingMessageFormatArguments() { // 1 MessageFormat pluralMessageFormatWithArgs = new MessageFormat( // 2 "{quantity, plural, " + "=0{There are no apples in the {location} farm.}" + "=1{There is one apple in the {location} farm.}" + "other{There are # apples in the {location} farm.}" + "}", ULocale.ENGLISH); // 3 Map patternArgs = new HashMap(); // 4 patternArgs.put("quantity", 0); patternArgs.put("location", "Normandy"); System.out.println(pluralMessageFormatWithArgs.format(patternArgs)); patternArgs.put("quantity", 2); patternArgs.put("location", "Washington"); System.out.println(pluralMessageFormatWithArgs.format(patternArgs)); }
- Create a
pluralizeUsingMessageFormatArguments
static method. - Initialize a
MessageFormat
named “pluralMessageFormatWithArgs”. As the first argument to the constructor, pass in an array bearing:- a map key value of “quantity”.
- an indication that it’s a plural pattern.
- sentences in plural forms in compliance with the PluralFormat syntax. “{location}” marks a placeholder with a map record key name of “location”. The current
MessageFormat
object will access this map record from the map passed in when calling itsformat
method.
- Pass an English ULocale as the 2nd argument to the
MessageFormat
constructor. - Create a
HashMap
namedpatternArgs
, place different values for its “quantity” key, put different placeholder values for the map record keyed “location”, and call thepluralMessageFormat.format
method, passing in thepatternArgs
map to it as an argument.
Secondly, let’s make sure to call this pluralizeUsingMessageFormatArguments
method inside the main method of our PluralizationJava
app:
public static void main(String[] args) { pluralizeUsingMessageFormatArguments(); }
Test it out
Let’s run our PluralizationJava
application and see if it works! We should now be able to see pluralization taking place while swiftly placing the provided placeholder values alongside them.
Pluralize with Lokalise
As we discovered, the seemingly effortless task of pluralization becomes a challenge to conquer the moment we add multiple locales to our project. But, at the end of the day, unless you’re coding for ‘Pluralization’ coursework at university, or your organization is focused exclusively on pluralization, you might reasonably hesitate to devote so many hours of work just to setting up pluralization in your application.
But, what if I told you there’s a much simpler, 1000x faster, and a million times more favorable way to handle string pluralization in any of your applications—both front-end and back-end?
Meet Lokalise, the translation management system that takes care of all your applications’ string pluralization wants and needs. With features like:
- Easy integration with various other services
- Collaborative translations
- Quality assurance tools for translations
- Easy management of your translations through a central dashboard
- Plus, loads of others
Lokalise will make your life a whole lot easier by letting you expand your properly pluralized applications to all the locales you’ll ever plan to reach, supported by an effective translation management system.
Your plurals handled automatically
With Lokalise, the whole jargon of pluralization is simplified to the mere click of a Plural
switch.
So, is there anything left to ponder at this point? Start with Lokalise in just a few steps:
- Sign up for a free trial (no credit card information required).
- Log in to your account.
- Create a new project under any name you like.
- Upload your translation files and edit them as required.
There you go! Almost before you could pluralize the word “hippopotamus” in your head, you have already completed the baby steps toward Lokalise-ing your application. See the Getting Started section for a collection of articles that will provide all the help you’ll need to kick-start the Lokalise journey. Also, refer to Lokalise API Documentation for a complete list of REST commands you can call on your Lokalise internationalization project.
Conclusion
In this step-by-step guide, we explored how some front-end and back-end languages—namely, JavaScript and Java—handle string pluralization. We created a basic JavaScript project and performed hardcoded pluralization on it. Then, we integrated a Pluralize third-party library to pluralize our English locale strings. Subsequently, we employed the help of another third-party library called Numerous to pluralize strings in multiple locales. Additionally, we looked into using Pluralize
for placeholders.
Moving on to the back end, we created a basic Java project and used the MessageFormat variant from ICU
to pluralize strings. We explored how MessageFormat
uses plural patterns and arguments passed to it to use as placeholder values.
So, the time has come for me to vaporize, so that you can go and pluralize. And, before it’s too late to apologize, make sure those hands are sanitized!
Further reading