Make WordPress Core

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#42170 closed defect (bug) (fixed)

Incorrect use of _n() in /wp-includes/class-wp-customize-nav-menus.php

Reported by: tobifjellner's profile tobifjellner Owned by: westonruter's profile westonruter
Milestone: 4.9 Priority: normal
Severity: normal Version: 4.9
Component: Customize Keywords: has-patch
Focuses: Cc:

Description

https://core.trac.wordpress.org/changeset/41812/ introduced a (probably) incorrect use of _n()

https://core.trac.wordpress.org/browser/trunk/src/wp-includes/class-wp-customize-nav-menus.php?marks=587#L587

                $this->manager->add_section( 'menu_locations', array(
	                        'title'       => _nx( 'View Location', 'View All Locations', $num_locations, 'menu locations' ),
	                        'panel'       => 'nav_menus',
	                        'priority'    => 30,
	                        'description' => $description
	                ) );

https://core.trac.wordpress.org/browser/trunk/src/wp-includes/class-wp-customize-nav-menus.php?marks=417#L417

                               'locationsTitle'         => _n( 'Menu Location', 'Menu Locations', $num_locations ),

If the idea is to use these phrases without numbers then it´s better to simply translate the two phrases separately.

When _n() is applied, you always need to include a count as a parameter in order for the function to pick the right form.
But there´s single specific number that would always, positively, for any language, mean just "plural without number".

So, _n() should be used only when the phrase contains the number that will lead to a certain form to be used. If it´s plain plural without number, then just the phrase should be translated as normally.
(In the same way, even if you have a number, but it´s hardcoded, like "this will be checked within 72 hours", then you can safely leave the phrase like that, no need to use _n() if 72 isn´t a variable parameter!)

Attachments (2)

42170.diff (2.1 KB) - added by felipeelia 7 years ago.
42170.2.diff (1.5 KB) - added by westonruter 7 years ago.
Condense

Download all attachments as: .zip

Change History (13)

#1 @felipeelia
7 years ago

  • Keywords close added

Hi @tobifjellner!

This change is related to #42112.

If the idea is to use these phrases without numbers then it´s better to simply translate the two phrases separately.

Yes, but we would have to include an if to test which one is needed, right?

When _n() is applied, you always need to include a count as a parameter in order for the function to pick the right form.

That number is $num_locations, the third parameter passed in both cases. As the decision of which string to pick is made based on that value it doesn't have to be presented on the screen, at least not in this case.

It's like the last part of translate_plural() function. If the counter is 1 we need the singular form, if it's 2 or more we need the plural form

return 1 == $count? $singular : $plural;

#2 @tobifjellner
7 years ago

Not really.
When a phrase is scraped with _n(), it will for most target languages create a matrix with two forms, just like in English.
But there are many languages that have more than two forms.
Russian, for example:
Singular is used for 1, 21, 31, 41, 51, 61, 71,... 101, 121...
"Dual" is used for 2, 3, 4, 22, 23, 24, 32, 33, 34,... 102, 103, 104, 122, 123...
Plural is used for 5-19, 25-29,... 105-119,...

If you just call this function with a "2", you´ll get the wrong form in Russian.
Maltese uses 5 different forms, depending on which number you´ve got.
So if you only want plural without numbers, just translate the plural phrase itself.

#3 @felipeelia
7 years ago

So @tobifjellner,

_n function allows translations for those 3 forms in Russian, even not showing the number:

https://translate.wordpress.org/projects/wp/dev/ru/default?filters%5Bstatus%5D=either&filters%5Boriginal_id%5D=5144943&sort%5Bby%5D=translation_date_added&sort%5Bhow%5D=asc

The decision is made on the number, but I don't think it has to be always shown, but I can be wrong, of course.

#4 @westonruter
7 years ago

  • Milestone changed from Awaiting Review to 4.9

This ticket was mentioned in Slack in #core-i18n by westonruter. View the logs.


7 years ago

#6 @ocean90
7 years ago

  • Component changed from Menus to Customize
  • Keywords needs-patch added; close removed

#7 in reply to: ↑ description @SergeyBiryukov
7 years ago

Replying to tobifjellner:

If the idea is to use these phrases without numbers then it´s better to simply translate the two phrases separately.

Right, if the goal is to make sure Menu Location is only displayed for one location (not for 21, 31, etc. in some languages), _n() should not be used for that. An explicit check should be used instead:

if ( 1 === $num_locations ) {
	$title = __( 'Menu Location' );
} else {
	$title = __( 'Menu Locations' );
}

@felipeelia
7 years ago

#8 @felipeelia
7 years ago

  • Keywords has-patch added; needs-patch removed

After @SergeyBiryukov clarifications it was clearer to me, sorry @tobifjellner. Just made a patch solving the issue :)

#9 @tobifjellner
7 years ago

@felipeelia Yes, that patch looks good!

@westonruter
7 years ago

Condense

#10 @westonruter
7 years ago

  • Owner set to westonruter
  • Resolution set to fixed
  • Status changed from new to closed

In 41816:

Customize: Fix string translations for singular vs plural after [41812].

Props felipeelia, tobifjellner, SergeyBiryukov.
See #42112.
Fixes #42170.

This ticket was mentioned in Slack in #core-i18n by felipeelia. View the logs.


7 years ago

Note: See TracTickets for help on using tickets.