Brief: интернационализация
Локализация строк и подписей
К локализации обращаются, когда одна логика работает на нескольких языках. Видимая пользователем строка — подпись класса, свойства, действия, формы, текст сообщения — локализуется идентификатором строковых данных в фигурных скобках внутри строкового литерала. При отправке значения на клиент платформа ищет каждый идентификатор в файлах проекта, имя которых заканчивается на ResourceBundle, в нужной локали и подставляет перевод; если перевода нет, остаётся сам идентификатор без скобок.
CLASS Book '{use.case.i18n.book}';
name '{use.case.i18n.book.name}' = DATA STRING[40] (Book);
Текущую локаль — язык, страну, часовой пояс — платформа берёт из свойств Authentication.language[CustomUser] и им подобных, а для действий, запущенных системой, — из локали сервера; пользовательские данные не переводятся. Механизм — интернационализация.
Аналогия: ключи ResourceBundle прямо в тексте подписи, а не вызов функции перевода.
Обратный перевод
Обратный перевод избавляет от расстановки идентификаторов вручную: подписи пишутся в коде обычным текстом на одном языке, а запись, значением которой этот текст является, платформа находит сама — ключом записи остается ее собственный идентификатор, а текст является ее значением. Включается параметром запуска logics.lsfStrLiteralsLanguage, задающим язык строковых литералов lsf-кода: при старте сервера по всем ResourceBundle файлам проекта в этой локали строится словарь значение -> идентификатор, и обычный литерал, совпавший со значением записи, при разборе кода заменяется её идентификатором и дальше ведёт себя как локализуемый. Ведущие и конечные пробелы в сопоставлении не участвуют и сохраняются вокруг подстановки, а литерал пустой или состоящий из одних пробелов не заменяется вовсе.
Замена касается любого обычного литерала, а не только подписей, поэтому технические строки — ключи JSON, адреса, форматы, внешние идентификаторы — записываются сырой формой строкового литерала, которая не участвует ни в локализации, ни в обратном переводе:
'content' // обычный: локализуется и при совпадении заменяется обратным переводом
r'rawContent' // сырой: ни того, ни другого