Как использование gettext может помочь мне здесь? - PullRequest
7 голосов
/ 09 декабря 2010

Я пытаюсь настроить способ, позволяющий участникам переводить строки на другие языки.Вы можете увидеть пример здесь: ПРОВЕРКА ПЕРЕВОДОВ

Кто-то порекомендовал мне использовать для этого встроенную в php функцию gettext () вместо того, что я уже использую для загрузки языковых файлов, чтоthis:

function loadLanguageFile($language, $file) {

    $temp = array();

    $data = file_get_contents('./'.$language.'/'.$file.'.'.$language.'.php');

    $codes = array (
        '/(\'\s*\.\s*\$)(.+?)(\s*\.\s*\')/',
        '/(=\s*\$)(.+?)(\s*\.\s*\')/',
        '/(\'\s*\.\s*\$)(.+?)(;)/',
        '/(\[\')(.+?)(\'\])/',
        '/<\?php/s', '/\?>/s', '/<\?/s'
    );
    $html = array (
        '{$2}',
        '= \'{$2}',
        '{$2}\';',
        '[$2]',
        '',
    );
    // Since we don't have the values for the vars.
    $data = preg_replace($codes, $html, $data);

    // We must change this because they are global.
    $data = str_replace('$txt', '$langEditor_txt', $data);
    $data = str_replace('$helptxt', '$langEditor_helptxt', $data);

    eval($data);

    if (isset($langEditor_txt)) {
        $temp['txt'] = $langEditor_txt;
        unset($GLOBALS['langEditor_txt']);
    }
    if (isset($langEditor_helptxt)) {
        $temp['helptxt'] = $langEditor_helptxt;
        unset($GLOBALS['langEditor_helptxt']);
    }

    return $temp;
}

Строки содержатся в файле с таким именем: ManageDPModules.english.php DreamPortal.english.php и т. д.

Эти файлы могут выглядеть следующим образом:при открытии в любом редакторе php и может иметь множество переменных $ txt:

<?php 
// Dream Portal (c) 2009-2010 Dream Portal Team 
// DreamPortal.english.php; @1.1 

global $scripturl, $context; 

// General Strings 
$txt['forum'] = 'Forum'; 
$txt['dream_portal'] = 'Dream Portal'; 
$txt['dp_core_modules'] = 'Collapse or Expand this Module'; 
$txt['dp_who_forum'] = 'Viewing the forum index of <a href="' . $scripturl . '?action=forum">' . $context['forum_name'] . '</a>.'; 
$txt['dp_who_portal'] = 'Viewing the portal index of <a href="' . $scripturl . '">' . $context['forum_name'] . '</a>.'; 
$txt['dp_who_page'] = 'Viewing the page &quot;<a href="' . $scripturl . '?page=%1$s">%2$s</a>&quot;.'; 
?>

Я использую следующую функцию для сохранения переводов:

function langSave($lang, $file) {

    // We just don't get values from the form, they have to exist in the english files to be taken seriously.
    $default = loadLanguageFile('english', $file);

    if ($default['txt']) {
        foreach ($default['txt'] as $key=>$string) {
            if (isset($_REQUEST['txt'.$key]) && str_replace(' ', '', $_REQUEST['txt'.$key]) != '') {
                $data.='$txt[\''.$key.'\'] = \''.str_replace("'", "\'", $_REQUEST['txt'.$key]).'\';'."\n";
            }
        }
    }
    if ($default['helptxt']) {
        foreach ($default['helptxt'] as $key=>$string) {
            if (isset($_REQUEST['helptxt'.$key]) && str_replace(' ', '', $_REQUEST['helptxt'.$key]) != '') {
                $data.='$helptxt[\''.$key.'\'] = \''.str_replace("'", "\'", $_REQUEST['helptxt'.$key]).'\';'."\n";
            }
        }
    }

    if (isset($data)) {
        $codes = array (// '' . $test . '
            '/(\{)(.+?)(\})/',
            '/(\'\' \. \$)(.+?)( \. \')/',
            '/(\' \. \$)(.+?)( \. \'\')/',
            '/(\[\')(.+?)(\'\])/',
            '/(\[)(.+?)(\])/',
        );
        $html = array (
            '\' . \$$2 . \'',
            '\$$2 . \'',
            '\' . \$$2',
            '[$2]',
            '[\'$2\']',
        );
        // Convert the data back to normal.
        $data = preg_replace($codes, $html, $data);

        $data = '<?php'."\n".$data.'?>';
        file_put_contents('./'.$lang.'/'.$file.'.'.$lang.'.php', $data);
    }
    languageHome();
} 

Функция языка:

function languageHome() {

    $languages = loadLanguageList();

    echo '
    Language List
        <table>';
    foreach ($languages as $language) {
        echo '
            <tr>
                <td>
                    '.$language.'
                </td>
                <td>
                    <a href="index.php?op=langView&lang='.$language.'">View</a>
                </td>
            </tr>';
    }
    echo '
        </table>';

}

Я не вижу, как поможет gettext.Невозможно обновить текстовый каталог без перезагрузки сервера каждый раз.Может быть, если кто-то может создать демо-версию этого для меня?

Кроме того, хотел бы, чтобы он поддерживал UTF-8.Данные должны быть согласованными.

Так что же не так с этой реализацией ??Зачем использовать gettext ??Как его можно использовать для улучшения перевода для работы как с языковыми строками UTF-8, так и без UTF-8, чтобы их можно было переводить .?

РЕДАКТИРОВАТЬ: Обратите внимание, что файлы будутв конечном итоге необходимо переименовать в: ManageDPModules.[language].php, DreamPortal.[language].php и т. д. и т. д., чтобы переводы работали.Итак, как каталоги помогут мне в этом отношении?Если вы хотите увидеть возможные переводы END-RESULT, вы можете скачать языковой пакет, расположенный по адресу здесь , и открыть языковые файлы .german.php, чтобы увидеть, как он должен выглядеть после того, как участник отправит язык нафайл за файломОтмечено, что некоторые из этих пакетов имеют строки UTF-8, а некоторые нет.Имя файла пакетов сообщит вам об этом.Было бы неплохо, если бы я также мог заставить его поддерживать UTF-8, но это не является обязательным требованием.Пожалуйста, обратите внимание, я не пытаюсь создать полные пакеты здесь.Я просто хочу создать языковой файл. [Language] .php со всеми переведенными внутри него строками (что мой код уже делает).

ОК, я предоставлю для этого ПОЛНЫЙ файл index.php, так чтовы можете увидеть, что именно делает, когда вы делаете переводы.Вот файл index.php для этого, и вам понадобятся файлы на английском языке: DreamPortal.english.php , ManageDPModules.english.php и DreamHelp.english-utf8.php .Теперь, чтобы увидеть это, вам нужно загрузить на сервер index.php, создать несколько папок, в которых находится index.php, вызвать 1 на английском и создать там папку для каждого дополнительного языка, который вы хотите (я сделал 2папки, испанский и французский), затем загрузите 3 языковых файла в английскую папку.Запустите index.php в вашем браузере, и вы увидите, что он работает.

Теперь, как я могу использовать gettext для каталогов с таким же подходом.Мне нужно включить онлайн-перевод файлов.Мне нужно создать PHP-файлы переводов в том же стиле, что и файлы .english.php с тем же PREFIX, что и до .english.php, и мне нужно изменить язык в имени файла на тот же язык, который определен для папкиназвание.Онлайн-переводы - ЕДИНСТВЕННЫЙ доступный метод.Переводчик должен сосредоточиться ТОЛЬКО на переводе строк.Они не должны фокусироваться на установке программ, их упаковке, переименовании файлов и т. Д. И т. Д. Это делает этот процесс максимально безболезненным, позволяя выполнять его в Интернете.И я знаю, что есть способ сделать это, и даже для поддержки UTF-8.Но я использую лучший из известных мне методов.Но многие из вас намного умнее, чем я, поэтому я прошу помощи у вас, ребята.

Есть ли кто-нибудь, кто может показать мне лучший способ?Пример, подобный тому, который я дал вам в этом вопросе?

Мне нужно разрешить переводы в режиме онлайн от переводчиков, а также, чтобы он поддерживал файлы UTF-8, а также файлы, не относящиеся к UTF-8. Мне нравится способ настройки по приведенной выше ссылке ( ПЕРЕВОДЫ ПЕРЕВОДОВ ), чтобы переводчики могли просто выполнять переводы онлайн и не беспокоиться ни о чем другом, а также автоматически создавали необходимые файлы. Это будет то же самое, что и английское имя файла с именем папки (представляющим язык) после первого . (точка), и оно должно иметь расширение .php (как в коде). Я сейчас пользуюсь). В общем, мне нужна адаптация текущего index.php для поддержки UTF-8 и не UTF-8 для всех или большинства языков, и мне сказали, что использование gettext () и файлов каталога поможет в этом.

Ищу модифицированную версию моего текущего index.php для использования gettext () таким образом, чтобы он поддерживал большинство, если не все, языки и переводы. REGEX, который я получил для preg_replace, не совсем удовлетворителен, потому что, кажется, он помещает косую черту перед двойными кавычками при сохранении / отправке переводов. Так что, возможно, понадобится и улучшение preg_replace.

Кстати, я предоставил полный пример с ACTUAL CODE. Я хотел бы, чтобы кто-то изменил этот пример, используя КОД, который я предоставил для ИСПОЛЬЗОВАНИЯ GETTEXT и поддержки UTF-8. Или фактически предоставьте мне ФАКТИЧЕСКИЙ МЕТОД, чтобы я мог сделать это сам. Не ищу кучу ссылок, которые я могу найти самостоятельно!

Спасибо!

Ответы [ 2 ]

13 голосов
/ 12 декабря 2010

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

Просто используйте одно из множества существующих решений.

  • Посетите каждый из них и отфильтруйте несущественные проекты
  • Изучите различия между остальными и выберите тот, который подходит вам лучше всего
  • Продолжайте разрабатывать и настраивать свои собственные потребности на основе существующего проекта
  • Если вы обнаружили ошибку или считаете, что оригинальный проект получит выгоду от ваших дополнений, свяжитесь с автором и сообщите ему

Вот некоторые моменты, которые следует учитывать при созданииВаши решения:

  • Язык проекта
  • Возможность расширять, добавлять функции и настраивать в соответствии с вашими потребностями
  • Это услуга?или с открытым исходным кодом, который вы можете загрузить и использовать на своем собственном сервере
  • Поддерживает ли он перевод множественного числа?
  • Сообщество и ресурсы, доступные для этого проекта
  • Имеется ли оно такжес веб-интерфейсом, как вы просили?

Вот некоторые (случайным образом упорядоченные):

Удачи!

Обновление: спасибо, Эль Йобо.Я отметил это как вики сообщества, любой может редактировать или отвечать в других проектах, если он найдет что-то еще.

6 голосов
/ 14 декабря 2010

Когда вам рекомендовали использовать gettext, на самом деле было рекомендовано использовать gettext- как систему перевода.Ваш текущий код сложен из-за мнемонических текстовых признаков.И проблема, с которой вы столкнулись с регулярными выражениями для редактирования, вызвана возни с переменными там.Позвольте мне предложить альтернативный код для переходных целей.

Прелесть gettext заключается в использовании ненавязчивого API.Вызов функции _() достаточно прост, чтобы его можно было тщательно использовать без добавления большого количества синтаксиса или раздувания кода.Это предпочтительнее таких вещей, как getTextTrans('ABBR_TXT_ID').Использование таких мнемонических текстовых идентификаторов является распространенной ошибкой;потому что на практике нет частых переписываний и _("Raw english original text.") служит той же цели.Однако, поскольку у вас уже есть мнемонические ключи, сохраните их, если их слишком много для изменения.Это всего лишь рекомендация.

Ваша настоящая проблема заключается в использовании встроенных выражений PHP для построения строк перевода.Именно поэтому регулярные выражения для вашего редактора перевода стали непрозрачными.Поэтому я настоятельно рекомендую использовать статические строки и указывать заполнители.Перед функцией перевода должна быть возложена обработка.(Не беспокойтесь о микрооптимизации здесь!) - я бы использовал {$url_xy} заполнители в стиле PHP / Smarty, например:

$txt['dp_who_forum'] = 'Viewing the forum index
of <a href="{$scripturl}?action=forum">{$forum_name}</a>.'; 

И функцию перевода, которая ищет глобальную таблицу заполнителей или параметры ($контекст) для замены:

function __($text, $params=array()) {
    global $txt, $txt_placeholders;
    if (isset($txt[$text])) {
        $text = $txt[$text];
    }
    if (strpos($text, '{$')) {
        $params = array_merge($params, $txt_placeholders);
        $text= preg_replace("/\{\$(\w+)\}/e", "$params['$1']", $text);
    }
    return $text;
}

Оптимизируемый.Но таким образом вы можете использовать статический мнемонический-> текстовый или английский-> текстовый набор массивов перевода. Вы используете только статические строки в вашем текстовом переводе.Эти статические строки отображаются как есть, и ваши переводчики редактируют текст на английском языке, но не какие-либо из {$placeholders}.

Следовательно, ваш код для функции перевода не будет нуждаться ни в каком сложномрегулярные выражения (в данном случае они бесполезны) для сопоставления строк и встроенных переменных PHP.На самом деле, вместо нее может появиться гораздо более простая комбинация include() и var_export():

function langSave($lang, $file) {
    $txt = array();
    include($file);   // assuming it contains a simple $txt = array(...

    foreach ($txt as $key=>$string) {
        $txt[$key] = $_REQUEST["txt$key"];
    }
    file_put_contents($file, "<?php\n\$txt =".var_export($txt,1).';?>');
}

Обработка файлов и тому подобное, конечно же, необходимо настроить.Но все же это более простой подход.

И он также позволит вам перейти к одному из вариантов gettext в качестве бэкэнда.Сохраните пользовательскую функцию оболочки __() и используйте, например, Zend_Translate в качестве бэкэнда.Это позволяет вам продолжать использовать ваши файлы перевода .php $ txt = array () (или я так думаю) или переходить к файлам .mo / .po в стиле gettext.Преимущество этого состоит в том, что в отличие от решений для домашних пивоваров имеется широкая поддержка инструментов.

В любом случае, вот как вы используете материал в своем основном приложении:

print "<a href='...'>" . __("link_text") . "</a>";
print __("dp_forum_link");   // uses e.g. $txt_placeholder["scripturl"]
print __("dp_param_link", array("scripturl"=>"http://override..."));

Переход от short_txtКлючи к английским-> массивам перевода иностранного текста были бы полезны в первую очередь, но теоретически любой из бэкэндов из ответа dvbs был бы применим.Теперь вы уже сказали, что нативный gettext не подходит для вас (для не-fastcgi PHP-установок сопротивление памяти является недостатком).Но нативные функции INTL PHP могут помочь вам.В частности, http://www.php.net/manual/en/class.messageformatter.php может быть более полезным, чем простая оболочка {$ var} для замены, которую я вам дал.Но я никогда не использовал его, и я думаю, что Zend_Translate, вероятно, более полезен.В частности, любой из этих бэкэндов может дать вам независимость от кодировки.Лично я бы просто придерживался UTF-8, несмотря ни на что.Но файлы gettext .mo / .po могут иметь, например, свой собственный набор символов.

...