Локализация
Плагин i18n для Luasmith предоставляет инструменты для создания многоязычных сайтов. Он использует Lettext, реализацию Gettext для Lua, позволяя переводить строки в шаблонах вашего сайта с использованием распространённого формата файлов PO. Плагин автоматически извлекает строки и генерирует PO(T) файлы при сборке веб-сайта, так что вам не понадобятся стандартные утилиты Gettext (такие как xgettext и msgmerge) — Lettext и плагин делают всё необходимое, чтобы упростить создание многоязычных сайтов.
Плагин не доделан. Хотя основные вещи завершены, все ещё есть некоторые важные нереализованные части. Ожидаются кардинальные изменения.
Структура содержимого
Для указания языка страницы вы можете либо использовать поле lang в метаданных, либо добавить суффикс к имени файла. Суффикс удобен, когда вы хотите использовать некоторые страницы как переводы друг для друга, и плагин учтёт это, позволяя создать переключатель языков (как тот, что вы можете видеть вверху этой страницы).
Предположим, каталог content выглядит следующим образом:
content/
| index.md
| index.ru.md
| some_page.md
И в some_page.md указано lang = ru; на выходе будет такая структура:
out/
| index.html
| ru/
| index.html
| some_page.md
Плагин сам отредактирует ссылки в содержимом страниц, так что их следует указывать так, как это корректно для структуры директории content, не беспокойтесь о том, что путь к корню поменяется.
Пайплайн
Для локализации ваших страниц потребуется всего 2 узла в пайплайне.
i18n.localize(defaultLang, potAsDefault)Этот узел проходит через все страницы, меняя пути и относительные ссылки так, как нужно; необходимые специфические поля у каждого элемента (item) также будут установлены.
defaultLang— код языка по умолчанию для вашего сайта. Страницы без указанного поляlangи без кода языка в суффиксе имени файла будут считаться страницами на языке по умолчанию. ЕслиdefaultLang- nil, то язык по умолчанию будетen.potAsDefaultустанавливает, будет ли файлmessages.potиспользоваться как резервный источник перевода строк для языка по умолчанию. Если язык по умолчанию имеет несколько форм множественного числа (как русский язык, например), то будет недостаточно использовать толькоmsgidиmsgid_pluralдля корректного отображения; еслиpotAsDefaultявляется true, вы можете добавитьmsgstrв POT файл, чтобы обойти ограничение и плагин успешно отобразит корректные строки; но это может быть несколько неправильно — писать "перевод" в POT файле (поскольку это PO Template, то есть шаблон), и в этом случае вы можете предпочесть указать false дляpotAsDefault, тогда отдельный PO файл будет сгенерирован для языка по умолчанию, а POT файл можно будет оставить чистым. ЕслиpotAsDefault- nil, то это то же, что он равен true.Если вы используете плагин
i18nвместе с другими плагинами, которые меняют пути страниц (полеpath), тогдаi18n.localizeдолжен быть вызван до узлов других плагинов, чтобы не потерять суффиксы с кодами языков.i18n.writeTranslations()Этот узел записывает все файлы для перевода в директорию
po. PO-файл будет сгенерирован для каждого языка, который плагин обнаружит, так что вам не нужно редактировать LINGUAS и/или создавать PO-файлы самостоятельно. Этот узел следует вызывать после применения шаблонов и других преобразований, которые вызывают фукнции перевода строк, чтобы плагин собрал все необходимые строки.
Также ещё пока что есть i18n.setLang(path, lang) как замена отсутствующему функционалу, чтобы установить язык и прочие вещи для страниц, сгенерированных в пайплайне (то есть не из папки content). Этот узел скорее всего будет удалён в будущем.
Использование в шаблонах
Бо́льшую часть функционала плагина для шаблонов можно изучить, взглянув на код переключения языков на этой странице:
<% if .nlangs > 1 then -%>
<div><%= _'Languages' .. ':' -%>
<% for lang, path in iterLangs() do
if l == lang then -%>
<b><%= getLangName(l) %></b>
<% else -%>
<a href="<%= p %>"><%= getLangName(l) %></a>
<% end -%>
<% end -%>
</div>
<% end -%>
nlangs — счётчик количества языков, на которых страница доступна. Для этой страницы непосредственно nlangs равен 2. Значение поля задаётся автоматически, не редактируйте его самостоятельно.
_'Languages' — строка для перевода. Если вы когда-нибудь писали код с использованием Gettext, то вам могут быть знакомы функции _(...), _p(...), _n(...) and _np(...) — это функции для перевода строк, со слегка отличающимися опциями, но главная задача у них одна: строка будет заменена на перевод из каталога сообщений для текущего языка (или оригинальная строка будет возвращена, если перевода нет). Посмотрите на демонастрционный скрипт Lettext для изучения детального использования этих фукнций.
Если посмотреть в файле ru.po среди исходников этого сайта, можно найти перевод для указанной строки:
msgid "Languages"
msgstr "Языки"
iterLangs() перебирает языки страницы, возвращая код языка и путь к странице на другом языке. Итератор также выдаст текущую страницу, что можно обнаружить, сравнив возвращённый код языка с кодом текущей страницы (lang).
getLangName(lang) возвращает название языка для предоставленного кода. На данный момент функция возвращает название на английском, но это изменится в будущем. Так что сейчас функция возвращает "English" для en и "Russian" для ru независимо от языка текущей страницы.
А теперь, ещё одна вещь, которую можно использовать в шаблонах:
getLangRoot() возвращает путь к корневой директории языка текущей страницы.
Планируемые изменения
- Добавление функции для получения даты и времени в локализованном формате;
- Добавление опции для создания поддиректории для языка по умолчанию (чтобы можно было сделать выбор языков на странице
index.html, а всё остальное поместить в поддиректории, подобно тому, что делает Википедия, с той разницей, что Википедия использует поддомены, а не поддиректории); getLangNameбудет возвращать локализованные названия языков;- Добавление простого способа создания локализованных индексных и других сгенерированных в пайплайне страниц.