Repository: ktorio/ktor
File: ktor-server/ktor-server-plugins/ktor-server-i18n/jvm/src/io/ktor/i18n/I18n.kt (Kotlin)

Code before:
        val bestMatchLanguage = acceptedLanguages.firstOrNull {
            it.value in availableLanguages
        }?.value ?: defaultLanguage

        it.attributes.put(REQUIRED_RESPONSE_LANGUAGE, bestMatchLanguage)

        val locale = Locale.forLanguageTag(bestMatchLanguage)
        it.attributes[LOCALE] = locale

        val bundle = ResourceBundle.getBundle(BUNDLE_KEY, locale)
        it.attributes[RESOURCE_BUNDLE] = bundle
    }

    onCallRespond { call ->
        val value = call.attributes[REQUIRED_RESPONSE_LANGUAGE]
        if (value.isNotBlank()) {
            call.response.header(HttpHeaders.ContentLanguage, value)
        }
    }
}

/**
 * Get the current accepted [locale](java.util.Locale) specified in the HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.locale)
 */
public val RoutingContext.locale: Locale get() = call.locale

/**
 * Get the current accepted [locale](java.util.Locale) specified in the HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.locale)
 */
public val ApplicationCall.locale: Locale get() = attributes[LOCALE]

/**
 * Translate a message key to an accepted language specified in HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.i18n)
 */
public fun ApplicationCall.i18n(@PropertyKey(resourceBundle = BUNDLE_KEY) key: String): String {
    val value = attributes[RESOURCE_BUNDLE].getString(key)

    I18N_LOGGER.debug {
        "translating to $locale: $key=$value"
    }
    return value
}

internal const val BUNDLE_KEY = "messages/messages"


Review comment (suggestion):
It's a little confusing having two properties on the routing context and call here.  Would probably be better to just have it on the call.



Code after:
            it.value in availableLanguages
        }?.value ?: defaultLanguage

        it.attributes[REQUIRED_RESPONSE_LANGUAGE] = bestMatchLanguage

        val locale = Locale.forLanguageTag(bestMatchLanguage)
        it.attributes[LOCALE] = locale

        val bundle = ResourceBundle.getBundle(BUNDLE_KEY, locale)
        it.attributes[RESOURCE_BUNDLE] = bundle
    }

    onCallRespond { call ->
        val value = call.attributes[REQUIRED_RESPONSE_LANGUAGE]
        if (value.isNotBlank()) {
            call.response.header(HttpHeaders.ContentLanguage, value)
        }
    }
}

/**
 * Get the current accepted [locale](java.util.Locale) specified in the HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.locale)
 */
public val ApplicationCall.locale: Locale get() = attributes[LOCALE]

/**
 * Translate a message key to an accepted language specified in HTTP request
 *
 * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.i18n.i18n)
 */
public fun ApplicationCall.i18n(@PropertyKey(resourceBundle = BUNDLE_KEY) key: String): String {
    val value = attributes[RESOURCE_BUNDLE].getString(key)

    I18N_LOGGER.debug {
        "translating to $locale: $key=$value"
    }
    return value
}

internal const val BUNDLE_KEY = "messages.messages"