[wp-trac] [WordPress Trac] #34308: The _n*() functions don't cater for a string that represents exactly one item

WordPress Trac noreply at wordpress.org
Thu Oct 15 05:51:52 UTC 2015


#34308: The _n*() functions don't cater for a string that represents exactly one
item
--------------------------------------+------------------------------
 Reporter:  johnbillion               |       Owner:
     Type:  enhancement               |      Status:  new
 Priority:  normal                    |   Milestone:  Awaiting Review
Component:  I18N                      |     Version:
 Severity:  normal                    |  Resolution:
 Keywords:  dev-feedback 2nd-opinion  |     Focuses:
--------------------------------------+------------------------------
Description changed by johnbillion:

Old description:

> The first and second parameters of `_n()` and `_n_noop()` are sometimes
> (incorrectly) thought to represent ''one item'' and ''more than one
> item''. They actually represent the ''singular form'' and the ''plural
> form'', and in languages that have complex plural structures the singular
> form can be used for numbers such as 21 and 31, not just 1.
>
> Recent tickets concerning this: #28502, #33239, #34127, #34307.
>
> The solution to requiring a string to represent exactly one item and
> another string to represent multiple items is usually to use some simple
> logic:
>
> {{{
> if ( 1 === $number ) {
>   _e( 'Item updated' );
> } else {
>   printf( _n( '%s item updated', '%s items updated', $number ),
> number_format_i18n( $number ) );
> }
> }}}
>
> This is fine in most cases, however a problem arises when you want to
> register strings for translation in advance of knowing the number. For
> this, `_n_noop()` is used, but in the example above we'd also need to use
> `__()` to register the string which represents exactly one item.
>
> While working on #32532, I came across a situation that would benefit
> from the introduction of a variant of `_n_noop()` which also caters for a
> string that represents exactly one item.
>
> In order to allow `bulk_post_updated_messages` to be provided in the post
> type labels array, the messages need to use `_n_noop()` as they're
> registered in advance of knowing the number. Unfortunately, the `locked`
> message is the ugly duckling here and also requires a string that
> represents exactly one item, in addition to the nooped singular and
> plural forms.
>
> This means that either a new bulk message needs to be introduced into the
> array (ugh), or the value of the message needs to be an array containing
> two items: the 'one item' string, and the nooped singular and plural
> forms. Both of these options turn this otherwise peachy array of nooped
> labels into a mess.
>
> The introduction of a function like `_n_noop()` but which also supports a
> string that represents exactly one item would allow us to do this:
>
> {{{
> array(
>         'updated'   => _n_noop( '%s post updated.', '%s posts updated.'
> ),
>         'locked'    => _XYZ_noop( '1 post not updated, somebody is
> editing it.', '%s post not updated, somebody is editing it.', '%s posts
> not updated, somebody is editing them.' ),
>         ),
>         'deleted'   => _n_noop( '%s post permanently deleted.', '%s posts
> permanently deleted.' ),
>         'trashed'   => _n_noop( '%s post moved to the Trash.', '%s posts
> moved to the Trash.' ),
>         'untrashed' => _n_noop( '%s post restored from the Trash.', '%s
> posts restored from the Trash.' ),
> );
> }}}
>
> The `translate_nooped_plural()` function could be altered to support a
> `$nooped_plural` array which also contains an element representing
> exactly one item, return it if so, and return the singular form if not.
>
> So, does this warrant the introduction of another l10n function?

New description:

 The first and second parameters of `_n()` and `_n_noop()` are sometimes
 (incorrectly) thought to represent ''one item'' and ''more than one
 item''. They actually represent the ''singular form'' and the ''plural
 form'', and in languages that have complex plural structures the singular
 form can be used for numbers such as 21 and 31, not just 1.

 Recent tickets concerning this: #28502, #33239, #34127, #34307.

 The solution to requiring a string to represent exactly one item and
 another string to represent multiple items is usually to use some simple
 logic:

 {{{
 if ( 1 === $number ) {
   _e( 'Item updated' );
 } else {
   printf( _n( '%s item updated', '%s items updated', $number ),
 number_format_i18n( $number ) );
 }
 }}}

 This is fine in most cases, however a problem arises when you want to
 register strings for translation in advance of knowing the number. For
 this, `_n_noop()` is used, but in the example above we'd also need to use
 `__()` to register the string which represents exactly one item.

 While working on #32532, I came across a situation that would benefit from
 the introduction of a variant of `_n_noop()` which also caters for a
 string that represents exactly one item.

 In order to allow `bulk_post_updated_messages` to be provided in the post
 type labels array, the messages need to use `_n_noop()` as they're
 registered in advance of knowing the number. Unfortunately, the `locked`
 message is the ugly duckling here and also requires a string that
 represents exactly one item, in addition to the nooped singular and plural
 forms.

 This means that either a new bulk message needs to be introduced into the
 array (ugh), or the value of the message needs to be an array containing
 two items: the 'one item' string, and the nooped singular and plural
 forms. Both of these options turn this otherwise peachy array of nooped
 labels into a mess.

 The introduction of a function like `_n_noop()` but which also supports a
 string that represents exactly one item would allow us to do this:

 {{{
 array(
         'updated'   => _n_noop( '%s post updated.', '%s posts updated.' ),
         'locked'    => _XYZ_noop(
                 '1 post not updated, somebody is editing it.',
                 '%s post not updated, somebody is editing it.',
                 '%s posts not updated, somebody is editing them.' )
         ),
         'deleted'   => _n_noop( '%s post permanently deleted.', '%s posts
 permanently deleted.' ),
         'trashed'   => _n_noop( '%s post moved to the Trash.', '%s posts
 moved to the Trash.' ),
         'untrashed' => _n_noop( '%s post restored from the Trash.', '%s
 posts restored from the Trash.' ),
 );
 }}}

 The `translate_nooped_plural()` function could be altered to support a
 `$nooped_plural` array which also contains an element representing exactly
 one item, return it if so, and return the singular form if not.

 So, does this warrant the introduction of another l10n function?

--

--
Ticket URL: <https://core.trac.wordpress.org/ticket/34308#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list