Интересные задачи верстки и клиентского программирования

Автоматический перевод lang файлов битрикса

добавил Шубин Александр 23 Апрель, 2016


Написал простенький скрипт для перевода lang файлов битрикса через яндекс переводчик. Скрипт будет вам полезен если сайт сделан грамотно, и весь текст шаблонов находится там где он должен быть в битриксе, то есть в lang файлах. Если есть текст непосредственно в шаблонах компонентов или в шаблоне сайта (в самом файле шаблона) или еще где-то кроме lang файла, то скрипт на него никак не повлияет. Если вы все же хотите воспользоваться скриптом, то сначала нужно весь текст вынести в lang файлы.

Пару слов по поводу качества перевода. От любого автоматического переводчика не стоит ждать многого. Если вы ждете, что для перевода всего сайта достаточно нажать одну кнопку и все будет идеально, то нет, я вас разочарую, по всем этим переведенным файлам потом придется идти еще раз и нещадно править текст. Почему был выбран перевод от яндекса? Потому что они предоставляют доступ к АПИ бесплатно. Если есть желание, можете купить платный доступ к апи гугла и переписать только функцию «translateString» в скрипте, она на входе получает строку на исходном языке и возвращает переведенную строку, можете сделать в этой функции перевод через любой другой сервис. Впрочем я сомневаюсь, что качество там будет заметно лучше.


Как работает скрипт?

Можете сразу исходный код посмотреть
http://verstaem.com/examples/translator/translator.php
Там не сильно сложно, порядка 300 строк кода. Я думаю разберетесь.

Если пересказать алгоритм словами, то скрипт работает следующим образом:

  1. Получает все подпапки в своей директории. То есть если вы положите скрипт в /local/translator.php, то скрипт получит все подпапки в папке /local
  2. Далее в каждой из найденных подпапок берутся свои подпапки до самого последнего уровня. Подпапки ищутся рекурсивно до тех пор не останется ни одной подпапки, либо до тех пор пока не будет найдена папка lang.
  3. Если папка lang найдена, то скрипт начинает перевод этой папки
  4. Внутри папки lang ищется подпапка указанного в параметрах языка. Если вы в параметрах скрипта указали перевод с русского(ru) на английский(en), то скрипт будет искать подпапку ru
  5. Если внутри папки lang нет подпапки ru, то выведется ошибка. Если подпапка ru найдена, то скрипт соберет все php файлы которые есть в папке ru и во всех ее подпапках
  6. Далее все найденные lang файлы переводятся. Каждый lang файл переводится отдельно. Внутри lang файла ищется массив $MESS и по каждому элементу этого массива отправляется запрос в яндекс переводчик на штатном апи яндекса, с помощью ключа
  7. Если lang файл уже переведен, то найденный исходный файл пропускается. То есть например файлы «/lang/ru/template.php» и «/lang/en/template.php» уже существуют, в этом случае файл «/lang/ru/template.php» переводиться не будет, чтобы его все же перевести в автоматическом режиме придется удалить файл «/lang/en/template.php»
  8. В каждой строке идет проверка на спец символы. Если у вас lang файле используются замены слов, например в файле хранится строка #TEST#, которая при выводе заменяется на значение какой то переменной, то этот файл я помечаю как обязательный к проверке. Проверка нужна потому, что яндекс может эту строку замены перевести, и соответственно при выводе будет просто текст внутри решеток и никакой замены на переменную не произойдет. К строке добавляется комментарий с текстом «!!!SYMBOL #»
  9. Аналогичную проверку на обязательную проверку я делаю на символ <, на случай если в lang файле есть html код. Теоретически html код не должен измениться, весь перевод осуществляется в спец. режиме «html», который яндекс заранее предусмотрел. Но я думаю строки с html кодом все же стоит заранее проверить. К строке добавляется комментарий с текcтом «!!!HTML»
  10. Кроме того, к каждой переведенной строке в lang файле добавляется комментарий вида «/!!AUTO!» и далее идет оригинальный текст. Таким образом можно сразу увидеть оригинальный текст в php комментарии и переведенный текст уже в элементе массива
  11. Далее отдельный переведенный lang файл сохраняется в нужной папке. Если вы переводите файл «/lang/ru/test/file.php» с русского на английский, то переведенный файл сохранится в «/lang/en/test/file.php». Каждый отдельный файл сохраняется независимо, до тех пор, пока эти самые lang файлы в папке не закончатся
  12. После того как вся папка lang переведена скрипт продолжает работу по рекурсивному обходу остальных директорий, пока не будет найдена следуюшая папка с именем lang

Вот такой примерно алгоритм. В конце простым print_r выведется список файлов которые нужно проверить, если этот список не вывелся можете поискать текст «!!!», то есть поискать три восклицательных знака во всех файлах. Вам все эти предупреждения поиск выдаст.

Как запустить?

Прежде чем начать зайдите по ссылке https://tech.yandex.ru/keys/get/ и создайте ключ. Без ключа скрипт не заработает, яндекс просто не будет ничего переводить.

Далее. Скачайте сам скрипт по ссылке http://verstaem.com/examples/translator/translator.php и сохраните внутри папки которую хотите перевести. Не нужно ложить скрипт в саму папку lang, в этом случае скрипт работать не будет, положите его на уровень выше, рядом с папкой lang, в этом случае скрипт сработает как надо. Кроме того нужно понимать что это все же php и время жизни скрипта у вас может быть ограничено, или там время ожидания ответа от апача у nginx какое то указано. В общем нужно понимать что тут есть ограничения по производительности. Поэтому в корень сайта скрипт ложить не стоит. Да! И перед запуском крайне рекомендую сделать резервную копию. Ничего плохого не должно произойти, но на всякий пожарный я думаю стоит это сделать.

По поводу настроек. В самом верху скрипта есть массив настроек

$params = array(
    'bitrix' => array(
        'from' => 'ru',
        'to' => 'en'
    ),
    'yandex' => array(
        'key' => '____YANDEX_KEY____',
        'from' => 'ru',
        'to' => 'en'
    ),
    'extensions' => array(
        'php'
    ),
    'permissions' => array(
        'file' => 0644,
        'folder' => 0755
    )
);

Тут в целом я думаю все понятно, но на всякий случай немного поясню.

  1. Первый блок настроек «bitrix». Переменная «from» это из какой папки брать оригинальные lang файлы, а переменная «to» это в какую папку их сохранять. В качестве теста можете там не просто en указать, а например «zzz» и проверить что там в папках zzz появится
  2. Второй блок настроек «yandex». Ключи «from» и «to» это с какого и на какой язык переводить. Вот тут можете посмотреть все варианты коды язков. Где получить ключ я выше дал ссылку, полученный ключ вставляете в переменную «key»
  3. Блок «extensions» на всякий случай сделал, вдруг у вас не просто php файлы лежат, а какие нибудь экзотические php5, вряд ли конечно, но может пригодится. Переводиться будут только lang файлы с указанным расширением
  4. Блок «permissions». Какие права скрипт должен назначать на созданные файлы и папки. Нужно именно число указывать, не строку.

После того как нужные параметры выставили и закачали скрипт в нужную папку просто откройте его в браузере. Если например вы его в папку /local положили, то откройте в браузере site.ru/local/translator.php чтобы он начал выполняться. После того как страница загрузится можете проверять результат.

Пример переведенного файла

<?php 
$MESS["SOCIAL_NETWORKS"] = "We in social networks"; // | !AUTO! Мы в соцсетях 
$MESS["SUBSCRIPTION"] = "Subscription"; // | !AUTO! Подписка 
$MESS["NEWS_SUBSCRIPTION"] = "To subscribe to news"; // | !AUTO! Подписаться на новости 
$MESS["ALL_PRICES"] = "<i class=\"fa fa-rub\"></i> — all prices are in rubles"; // !!!HTML | !AUTO! <i class="fa fa-rub"></i> &mdash;&nbsp;все цены указаны в&nbsp;рублях 
$MESS["MADE_IN"] = "Made in"; // | !AUTO! Сделано в 
$MESS["DESKTOP_VERSION"] = "The desktop version of the site"; // | !AUTO! Десктоп-версия сайта 
$MESS["ADDED_TO_CART"] = "Product successfully added to <a href=\"#URL#\">cart</a>"; // !!!SYMBOL # | !AUTO! Товар успешно добавлен в <a href="#URL#">корзину</a>

Это пример файла который необходимо проверить вручную. Обратите внимание на комментарии php. Тут ширина текста маленькая, поэтому с переносами не очень смотрится, но итоговый вариант я думаю понятен

Кратко суть поста еще раз

Чтобы перевести всякие компоненты и шаблоны закидываете файл translator.php на сайт в какую нибудь папку где есть lang подпапки (не важно на каком уровне), открываете скрипт в браузере и наслаждаетесь переводом вида ссылка 🙂


добавил Шубин Александр 23 Апрель, 2016
Рубрика: Программы


6 комментариев

  • Cryptos:

    Замечательный скрипт со всех сторон.
    Вопрос: в папке /lang/en/ (есть файлы — их переводит нормально в дерикторию ru)? но вот подпапки не переводит /lang/en/admin/.
    В чем проблема?

    • Баг. Исправил. Скачайте скрипт по ссылке из поста заново. Там кеширование, так что перед скачиванием нажмите F5 на всякий случай.

      В 198 строке добавил параметр один, поддиректории обходились, а lang файлы из них не собирались. Теперь собираются и соответственно корректно файлы подразделов переводятся.

  • mitnck:

    Немного или я туплю или скрипт. есть у меня три файла на разных языках.
    Структура

    в скрипте поменял $mess на $lang. На выходе получаю:

    $lang[«Signup»] =»»; // | !AUTO! Signup
    $lang[«Sign In»] =»»; // | !AUTO! Sign In
    $lang[«Restaurant Signup»] =»»; // | !AUTO! Restaurant Signup

    • Извиняюсь, тьма спама и нет особо времени его рассматривать, поэтому с задержкой отвечу, хоть это и не актуально уже наверное 🙂

      А зачем менять $MESS (регистр важен!) на $lang?
      В битриксовских файлах именно $MESS используется.
      В моем скприте файл с переменной просто инклудом подключается и в нем берется массив $MESS
      Дальше массив $MESS перебирается и каждое значение переводится. Если вы что-то правили, то выложите исправленный вариант скрипта, я посмотрю что не так было исправлено

  • mitnck:

    Сорри!

    Структура начальная:

    Вообщем из массива значение убирает совсем, и ставит его в не переведенном виде в комент

  • mitnck:

    епт! опять не вышло….

    видимо низя php теги впихивать )

    $lang[«Signup»] =»Signup»»;
    $lang[«Sign In»] =»Sign In»;
    $lang[«Restaurant Signup»] =»Restaurant Signup»;

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *