Интернационализация на веб-сайте, основанном на Ktor

#kotlin #web #internationalization #ktor

Вопрос:

Я новичок в Ktor и Котлине в целом, поэтому, пожалуйста, наберитесь терпения.

В настоящее время я пытаюсь создать небольшой веб-сайт (в основном для обучения), который использует файлы ключевых значений для интернационализации.

Я уже делал что-то подобное в PHP, где я просто расшифровал файл JSON и получил значение, связанное с переданным мной ключом. Таким образом, я мог бы сделать что-то как <p><?php echo $langJson["presentation"][0];?></p> (с $langJson, являющимся моим файлом ключа-значения json), чтобы получить правильный перевод.

Я пытаюсь сделать эквивалент в Котлине, используя Ktor, но я не знаю, как это сделать. Я нашел плагин aymanizz ktor-i18n на GitHub, который позволяет использовать i18n для интернационализации, но я не знаю, действительно ли он адаптирован к тому, что я хочу сделать, поскольку он определяет язык в заголовке, а не выбирается пользователем (например, с _GET).

У кого-нибудь есть хоть малейшее представление о том, как я мог бы это сделать?

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

Спасибо вам всем! 🙂

Ответ №1:

Основная идея состоит в том, чтобы получить код языка из запроса (параметр запроса, заголовок и т. Д.), сгенерировать путь к файлу ресурсов i18n, прочитать его, а затем десериализовать JSON в карту. Полученную карту можно использовать как есть или передать в качестве модели шаблону.

Вот пример, в котором я использую kotlinx.сериализацию для преобразования строки JSON, чтобы получить механизм шаблонов map и FreeMarker для визуализации HTML. Чтобы переключить язык, просто используйте параметр lang GET, например,. http://localhost:8080/?lang=es

 import freemarker.cache.ClassTemplateLoader
import io.ktor.application.*
import io.ktor.freemarker.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

fun main() {
    embeddedServer(Netty, port = 8080) {
        install(FreeMarker) {
            templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates")
        }

        routing {
            get("/") {
                call.respond(FreeMarkerContent("index.ftl", mapOf("i18n" to loadI18n(call.request))))
            }
        }
    }.start()
}

fun loadI18n(request: ApplicationRequest): Map<String, String> {
    val language = request.queryParameters["lang"] ?: "en"
    val filePath = "i18n/$language.json"
    val data = object {}.javaClass.classLoader.getResource(filePath)?.readText() ?: error("Cannot load i18n from $filePath")
    return Json.decodeFromString(data)
}
 

ресурсы/шаблоны/индекс.ftl

 <html>
<body>
    <h1>${i18n.greetings}</h1>
</body>
</html>
 

ресурсы/i18n/en.json

 {
  "greetings": "Hello"
}
 

ресурсы/i18n/es.json

 {
  "greetings": "Hola"
}
 

Комментарии:

1. Я пытаюсь сделать это прямо сейчас! Спасибо вам за быстрый и хорошо разработанный ответ