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

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

Я имею в виду 2 случая.

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

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

спасибо

4 ответов


ваш лучший вариант-использовать функцию 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 ткнул %s " на любой язык, который вы хотели, без изменения %s строка заполнителей. Они будут заменены на выходе функцией translate () с user1 и user2 соответственно. Вы можете прочитать больше о sprintf () в руководстве PHP для более продвинутых применений.

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

<?php

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

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

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

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

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

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

мои 2 цента.


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


@Julian

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

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