Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Cross-platform format specification + libraries for handling plurals/genders/conditionals for Go, Java, JS, Obj-C, Perl, PHP, Python, and Rust

License

NotificationsYou must be signed in to change notification settings

loctools/plurr

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Handling plurals, genders and conditionals in strings is not a particularlyfavorite task for programmers for many reasons. There's no common agreementon how to handle such variants, so all existing approaches are eitherplatform-specific (like gettext/po), or have limitations (for example youcan't have multiple plurals in one string), or not particularly translator-friendly, like Java's MessageFormat/ChoiceFormat.

Plurr is a universal format specification for handling plurals, genders,conditionals and placeholders designed to be easy to support fordevelopers and understandable for translators yet robust to support differentlanguage requirements. Plurr formatters are implemented in:Go, Java, JavaScript, Objective-C, Perl, PHP, Python, and Rust. Feel free tocontribute to this project and provide support for your favorite languages.

Advantages

  1. You can use Plurr with any L10N library of your choice: you can store andread Plurr-formatted messages the same way as you do for any other strings.
  2. Same string format across multiple languages means that strings can bereused more effectively. This all reduces the time and cost of translation.
  3. Named placeholders provide a great context for translators, and this meansbetter translation quality.
  4. Named placeholders allow to change their order in the final string if thisis more appropriate for a particular target language.
  5. Less programmatic string concatenation also helps understand the message asa whole.

Syntax Example

Do you want to delete{N_PLURAL:this{N} file|these{N} files} permanently?

Which, depending on the providedN value, will render as (for English):

  • N = 1, N_PLURAL = 0:Do you want to delete this 1 file permanently?
  • N = 5, N_PLURAL = 1:Do you want to delete these 5 files permanently?

The value of N_PLURAL is determined by calling a plural() function with thevalue of N, and is language-dependent. By default, plurals are calculatedautomatically: whenFOO_PLURAL placeholder is found and its value is notprovided to the formatting function, Plurr will try to doFOO_PLURAL = plurals(FOO) internally, taking into consideration the currentlocale defined for the Plurr object. Below is a sample JavaScript code:

varp=newPlurr();// create a Plurr object (once). Default locale is English...alert(p.format("Do you want to delete {N_PLURAL:this {N} file|these {N} files} permanently?",// message{'N':5}// parameters));

The syntax itself is not something new, it is similar to the one used in thealready mentioned Java's MessageFormat, but it is minimalistic and contains nosensitive words that translators can inadvertently change (and break).

Format specification

1. Simple named placeholders

Format

{NAME}

Example

{FOO} and{BAR}

Here{FOO} will be substituted with the provided FOO value, and{BAR} —with the value of BAR.

Recommended is the use of capitalA..Z and_ symbol — this makesplaceholders stand out in the text, which gives some additional clue totranslators that these sequences are something special and should not betranslated.

There are no restrictions on placeholder names, except that they must notcontain} or: symbol.

When you need to represent symbols{ or} themselves in the final string,replace them with named placeholders with corresponding values, for example:

alert(p.format("I love {<}curly{>} braces.",{'<':'{','>':'}'}));

2. Placeholders with alternatives

{CHOICE:FORM0[|FORM1][|FORM2][|FORM3][|...]}

where:

  • CHOICE is a zero or a positive integer.
  • FORM0,FORM1 and so on are the alternative versions of the string foreach value of CHOICE (starting from 0).

If less forms are provided than the value ofCHOICE, the last form is used.

As| is used to delimit different alternatives, in order to display suchsymbol in the final string, replace it with named placeholder with thecorresponding value (same as for{ and} in the section above).

Example in English:

{N_PLURAL:{N} file|{N} files}

will render as:

  • N = 0, N_PLURAL = 1:0 files
  • N = 1, N_PLURAL = 0:1 file
  • N = 2, N_PLURAL = 1:2 files
  • N = 5, N_PLURAL = 1:5 files

Example of the same string translated into Russian:

{N_PLURAL:{N} файл|{N} файла|{N} файлов}

will render as:

  • N = 0, N_PLURAL = 2:0 файлов
  • N = 1, N_PLURAL = 0:1 файл
  • N = 2, N_PLURAL = 1:2 файла
  • N = 5, N_PLURAL = 2:5 файлов

3. Multiple placeholders in the same string

Inside a string, there can be multiple placeholders of any kind.

Example:

{X_PLURAL:{X} file|{X} files} foundin{Y_PLURAL:{Y} folder|{Y} folders}.Do you want to{COMMAND:copy|move|delete}{X:them|it|them}?

Here, in addition to handling plurals, we use a value ofCOMMAND placeholderto display different verbs.

Same example in Russian:

В{Y_PLURAL:{Y} папке|{Y} папках|{Y} папках}{X_PLURAL:найден{X} файл|найдены{X} файла|найдено{X} файлов}.Хотите{X:его|их}{COMMAND:скопировать|переместить|удалить}?

4. Handling genders

Handling genders is the same as handling any other type of placeholders. Youjust need to provide a parameter (let's name itGENDER), which evaluates to,say,0 for male,1 for female, and2 in case the gender is unknown (theway you number genders is purely arbitrary, but we recommend sticking to somescheme that you use consistently across your application). Then all you need todo is to construct a message like this:

Do you want to leave{GENDER:him|her|them} a message?{GENDER:He|She|They} will see it when{GENDER:he|she|they}{GENDER:logs|logs|log} in.

5. Nested placeholders and special cases

Sometimes one would like to say "One file" instead of "1 file", and "No files"instead of "0 files". That's (and other scenarios) are possible with nestedplaceholders:

{X:No files|One file|{X}{X_PLURAL:file|files}} found.

Here we first make a choice based on the value ofX, where for values0 and1 we renderspecial messages, and for values2 and above we render the nested plural-aware placeholder.

Same example in Russian:

{X:Не найдено файлов|Найден один файл|{X_PLURAL:Найден{X} файл|Найдено{X} файла|Найдено{X} файлов|}}.

Such an approach allows translators to provide most natural translationpossible, and gives some peace of mind to developers helping them reduce theamount of supportingif...else code in their applications.

Syntax Highlighting

Plurr also has asyntax highlighteravailable forCodeMirror, which is a part of the live demo.


[8]ページ先頭

©2009-2025 Movatter.jp