спецификация формата для аргумента 2, как в 'msgstr[0]', не существует в 'msgid_plural'

У меня есть следующий код:

public function bulk_updated_messages ( $bulk_messages = array(), $bulk_counts = array() ) {

    $bulk_messages[ $this->post_type ] = array(
        'updated'   => sprintf( _n( '%1$s %2$s updated.', '%1$s %3$s updated.', $bulk_counts['updated'], 'yosilose' ), $bulk_counts['updated'], $this->single, $this->plural ),
        'locked'    => sprintf( _n( '%1$s %2$s not updated, somebody is editing it.', '%1$s %3$s not updated, somebody is editing them.', $bulk_counts['locked'], 'yosilose' ), $bulk_counts['locked'], $this->single, $this->plural ),
        'deleted'   => sprintf( _n( '%1$s %2$s permanently deleted.', '%1$s %3$s permanently deleted.', $bulk_counts['deleted'], 'yosilose' ), $bulk_counts['deleted'], $this->single, $this->plural ),
        'trashed'   => sprintf( _n( '%1$s %2$s moved to the Trash.', '%1$s %3$s moved to the Trash.', $bulk_counts['trashed'], 'yosilose' ), $bulk_counts['trashed'], $this->single, $this->plural ),
        'untrashed' => sprintf( _n( '%1$s %2$s restored from the Trash.', '%1$s %3$s restored from the Trash.', $bulk_counts['untrashed'], 'yosilose' ), $bulk_counts['untrashed'], $this->single, $this->plural ),
    );

    return $bulk_messages;
}

И затем в моем файле .po у меня есть:

#, php-format
msgid "%1$s %2$s updated."
msgid_plural "%1$s %3$s updated."
msgstr[0] "%1$s %2$s actualizado/a."
msgstr[1] "%1$s %3$s actualizados/as."

Но когда я пытаюсь создать свой файл .mo с помощью Poedit, я получаю эту ошибку:

a format specification for argument 2, as in 'msgstr[0]', doesn't exist in 'msgid_plural'

Я не понимаю, что здесь не так. Это то, как я называю «_n», или что-то в моей переведенной строке?

Я вижу, что это как-то связано с маркерами позиции sprintf... этому poedit явно не нравится, что у меня есть $3%s в msgid_plurals, а не в msgid... но не следует ли просто переводить строку "как есть"? Я передам переведенные строки в sprintf во время выполнения, вставив соответствующие существительные на место...


person yivi    schedule 19.11.2014    source источник


Ответы (1)


Дело не в том, что Poedit это не нравится, это инструмент gettext msgfmt — и ваш способ делать множественное число не проходит проверку на работоспособность. Как вы заметили, причина в том, что вы должны использовать одинаковые аргументы как в msgid, так и в msgid_plural. Просто сделай это.

Если вам интересно, почему, то это потому, что ваш код игнорирует возможность того, что в некоторых языках может быть больше (или меньше!), чем просто две формы, единственное и множественное число. В славянских языках их 3, в арабском — 6, в японском — всего 1. Ваш код никогда не сможет правильно работать с этими языками.

Как это часто бывает, в руководстве GNU gettext этот вопрос обсуждается довольно подробно: http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html

person Václav Slavík    schedule 20.11.2014
comment
Пытаюсь сделать вещи динамичными и ломаю голову над этим... :P Как вы думаете, будет ли что-то подобное правильным способом выполнить то, что я хочу? 'updated' => sprintf( _n( '%1$s %2$s обновлено.', '%1$s %2$s обновлено.', $bulk_counts['updated'], 'yosilose' ), $bulk_counts ['updated'], _n($this-›single, $this-›plural, $bulk_counts['updated'] ) ), я протестировал его, и он работает, я только беспокоюсь, что это не правильный или лучший способ сделайте это... Большое спасибо за вашу помощь. - person yivi; 20.11.2014
comment
Ну, форматирование комментариев испорчено. Но если это сработает, я могу обновить свой вопрос или отредактировать ваш ответ для будущих искателей. - person yivi; 20.11.2014
comment
@yivi Прочтите связанный раздел руководства, в нем объясняется, что правильно делать и почему. Ваша ошибка заключается в том, что вы используете %2$s в качестве заполнителя для правильного слова в первую очередь — это не может хорошо говорить, и даже если вам удастся что-то хоть немного работающее, ваши переводчики возненавидят вас (и сделают готовые переводы). - person Václav Slavík; 20.11.2014
comment
@yivi Кроме того, никогда не рекомендуется передавать что-либо, кроме строковых литералов, в качестве строковых аргументов _n (или любой другой функции gettext). Никогда, никогда не делай этого. Это делает фактические строки неизвлекаемыми. Вы действительно должны прочитать руководство, оно объясняет все эти вещи подробно — и хорошо. - person Václav Slavík; 20.11.2014
comment
Да, я прочитал документы, которые вы связали, спасибо. Опять же, я, вероятно, просто не понимаю это хорошо. Мои извинения. Теперь я понимаю, что передавать что-либо еще, кроме литералов, в функции gettext - не очень хорошая идея. Моя мысль заключалась в том, что, поскольку $2%s будет заменено другим вызовом _n(), с тем же числом в качестве квантификатора, что и первый вызов _n(); перевод сработал бы (и будущие переводчики не возненавидели бы меня). - person yivi; 20.11.2014
comment
Обычно это должно работать. У меня была такая ошибка, когда я случайно изменил %d на %s в переводе. - person xavier bs; 04.09.2020