Подтвердить что ты не робот

Как gettext обрабатывает динамический контент?

В php (или, возможно, gettext вообще), что делает gettext, когда видит переменную в динамическом контенте?

У меня есть 2 случая.

1) Скажем, у меня есть <?=$user1?> poked John <?=$user2?>. Возможно, на каком-то языке порядок слов отличается. Как gettext обрабатывает это? (нет, я не строю facebook, это был всего лишь пример)

2) Скажем, я сохраняю некоторые категории в базе данных. Они редко, но они хранятся в базе данных. Что произойдет, если я сделаю <?php echo gettext($data['name']); ?>? Я бы хотел, чтобы переводчики также переводили имена этих категорий, но нужно ли это делать в самой базе данных?

Спасибо

4b9b3361

Ответ 1

Ваш лучший вариант - использовать функцию spritf(). Затем вы должны использовать нотацию printf для обработки динамического содержимого в своих строках. Вот некоторая функция, которую я нашел здесь некоторое время назад, чтобы легко справиться с этим:

function translate()
{
    $args = func_get_args();
    $num = func_num_args();
    $args[0] = gettext($args[0]);

    if($num <= 1)
      return $args[0];

    return call_user_func_array('sprintf', $args);

}

Теперь, например, 1, вы хотите изменить строку на:

%s poked %s

Что вы ввели бы в функцию translate() следующим образом:

<?php echo translate('%s poked %s', $user1, $user2); ?>

Вы будете разбирать все функции translate() с помощью poEdit. а затем перевести строку "% s poked% s" на любой язык, который вы хотели, без изменения строковых заполнителей % s. Они заменили бы на выходе функцией translate() с user1 и user2 соответственно. Вы можете прочитать больше о sprintf() в руководстве PHP для более продвинутых способов использования.

Для вопроса №2. Вам нужно будет создать статический файл, который poEdit может анализировать, содержащий имена категорий. Например, "misctranslations.php":

<?php

_('Cars');
_('Trains');
_('Airplanes');

Затем выполните poEdit parse misctranslations.php. Затем вы сможете вывести преобразование имени категории с помощью <?php echo gettext($data['name']); ?>

Ответ 2

Чтобы немного поработать над тем, что сказал Марк... единственная проблема с вышеупомянутым решением состоит в том, что статический список должен всегда поддерживаться вручную, и если вы добавите новую строку перед всеми остальными или полностью измените существующую, мягкий, который вы используете для перевода, может путать новые строки, и вы можете потерять некоторые переводы.

Я на самом деле пишу статью об этом (слишком мало времени, чтобы закончить это в ближайшее время!), но мой предложенный ответ выглядит примерно так:

Gettext позволяет хранить номер строки, который строка выводит в коде внутри файла .po. Если вы полностью измените строку, редактор .po будет знать, что строка не нова, но она старая (благодаря номеру строки).

Моим решением для этого является написать script, который читает базу данных и создает статический файл со всеми строками gettext. Большая разница с решением Mark заключается в том, чтобы иметь первичный ключ (пусть его ID) в базе данных соответствует номеру строки в новом файле. В этом случае, если вы полностью измените один исходный перевод, линии будут все те же, а ваш переводчик будет распознавать строки.

Конечно, могут быть более новые и более интеллектуальные редакторы .po там, но, по крайней мере, если ваши проблемы с новыми строками, то это решит их.

Мои 2 цента.

Ответ 3

@Julian

Я думаю, что ваш подход не будет хорошо работать на практике. Представьте, что вы перемещаете некоторую функцию по коду. Номер строки будет отличаться, и имя файла может отличаться.

Я думаю, что единственным разумным способом управления изменением идентификаторов перевода было бы попытаться найти похожие идентификаторы в вашем .po файле. Редактор может показать предложение о слиянии нового текста перевода с существующим, если они очень похожи и нет строки перевода в сохраненном номере строки в вашем коде.

Ответ 4

Если у вас есть код в вашем коде: <?=sprintf(_('%s poked %s'), $user1, $user2)?> и один из ваших языков нуждается в замене аргументов, это очень просто. Просто переведите свой код следующим образом: msgid "%s poked %s" msgstr "%2$s translation_of_poked %1$s"