Создание мультиязычных приложений на LuaПодписка на Комментарии к "Создание мультиязычных приложений на Lua"

Аватар xxblx

В этой записи речь пойдет о создании мультиязычных приложений на Lua средствами самой Lua, не прибегая к использованию сторонних библиотек и модулей.

Для реализации мультиязычности в Lua будем использовать таблицы.

Рассмотрим первый вариант. Общая таблица под все языки, элементами которой являются другие таблицы - таблицы непосредственно с переводами.
Создаем необходимые таблицы

> tr = {} -- таблица под переводы
> tr.ru = {} -- таблица под русский перевод
> tr.en = {} -- таблица под английский перевод

Добавляем строки в таблицы tr.ru и tr.en

> tr.ru.helloMsg = "Привет"
> tr.en.helloMsg = "Hello"
> print(tr.ru.helloMsg)
Привет
> print(tr.en.helloMsg)
Hello

Помимо записи вида tr.ru.helloMsg доступ к значению helloMsg так же можно получить записями вида
> print(tr['ru']['helloMsg'])
Привет
> print(tr['ru'].helloMsg)
Привет

Создавать таблицы и их элементы можно тоже по другому принципу

> tr = {}
> tr['ru'] = {}
> tr['en'] = {}
> tr['ru'].helloMsg = "Привет"
> tr['en'].helloMsg = "Hello"
> print(tr['ru'].helloMsg)
Привет
> print(tr['en'].helloMsg)
Hello
> print(tr['ru']['helloMsg'])
Привет
> print(tr.ru.helloMsg)
Привет

Значение текущего используемого перевода в программе можно хранить в отдельной переменной

> lang = 'ru'
> print(tr[lang].helloMsg)
Привет
> lang = 'en'
> print(tr[lang].helloMsg)
Hello

Если говорить о создании программ, а не скриптов в пару строк, то перевод, как правило, хранится в отдельном файле(ах) (в данном случае, именно в отдельном файле). Допустим, этим файлом будет translation.lua, со следующим содержимым:

tr = {}
tr['ru'] = {}
tr['en'] = {}

tr['ru'].open = "Открыть"
tr['ru'].save = "Сохранить"
tr['ru'].about = "О программе"
tr['ru'].quit = "Выход"

tr['en'].open = "Open"
tr['en'].save = "Save"
tr['en'].about = "About"
tr['en'].quit = "Quit"

Для использования перевода, нужно только загрузить файл

> translation = require('translation')
> lang = 'ru'
> print(tr[lang].about)
О программе
> lang = 'en'
> print(tr[lang].about)
About

Поскольку не всегда и не всем удобно хранить все переводы в одном файле, рассмотрим второй вариант. Хранение каждого перевода в отдельном файле.
Допустим, переводы у нас будут лежать в каталоге translations и называться ru.lua и en.lua.

[xxblx@localhost 123]$ find ./
./
./translations
./translations/en.lua
./translations/ru.lua

Содержание файлов
ru.lua:

tr = {}
tr.open = "Открыть"
tr.save = "Сохранить"
tr.about = "О программе"
tr.quit = "Выход"

en.lua:

tr = {}
tr.open = "Open"
tr.save = "Save"
tr.about = "About"
tr.quit = "Quit"

В этом случае, нам нужно загружать только конкретный файл с переводом в зависимости от значения переменной lang

> lang = 'ru'
> translation = require('translations/'..lang)
> print(tr.about)
О программе

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

> lang = 'en'
> print(tr.about)
О программе

По этому потребуется дополнительно перезагрузить файл с переводом

> package.loaded.translation = nil
> lang = 'en'
> translation = require('translations/'..lang)
> print(tr.about)
About

Чтобы было наглядней

> lang = 'ru' -- устанавливаем русский язык
> translation = require('translations/'..lang) -- загружаем файл с переводом
> print(tr.about) -- выводим tr.about
О программе
> lang = 'en' -- меняем язык на английский
> print(tr.about) -- а tr.about выдает все еще на русском, т.к. файл с переводом не был перезагружен
О программе
> package.loaded.translation = nil -- присваиваем nil
> translation = require('translations/'..lang) -- загружаем файл заново
> print(tr.about) -- выводим tr.about, на этот раз выдает уже на английском, т.к. парой строк выше было lang = 'en'
About

Само собой, файлы с переводом необязательно держать в отдельном каталоге, можно и в одном с программой

[xxblx@localhost 123]$ find ./
./
./en.lua
./ru.lua

> lang = 'ru'
> translation = require(lang)
> print(tr.about)
О программе

Как видно из представленного выше, оба варианта можно использовать для создания мультиязычности в Lua, используя при этом только возможности самого языка, не прибегая к сторонним библиотекам и модулям. Какой именно лучше выбрать вариант - зависит от ситуации.
Плюс первого варианта - отсутствие необходимости перезагрузки файла с переводом. Плюс второго - удобно, если переводчиков несколько и используется, например, система контроля версий (git, svn и т.д.) или платформа управления локализацией (например, transifex). Переводчик вносит изменения только в свой файл, не трогая другие. К тому же, если будет оставлена незакрытая кавычка, поставлена лишняя скобка и т.п. это заденет только один файл, а значит, только один перевод, а не все разом.

Похожие материалы:

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