Это старый вопрос, но я наткнулся на него как на душу в поисках ответов, и единственным доступным ответом была ссылка без контекста. Так что здесь немного больше глубины, основанной на моем последующем копании.
Доступ к заголовку Accept-Language
Запрос объекта request
в соответствующем контроллере:
request.env['HTTP_ACCEPT_LANGUAGE'] #returns nil or a string, e.g.:
# => "en-AU,en-US;q=0.7,en;q=0.3"
Это легкая часть, хотя. Чтобы эффективно использовать его в Rails, вам нужно проанализировать эту строку (или, может быть, это nil
?).
Боковая панель: учебник по заголовкам Accept-
Итак, глядя на приведенный выше пример строки, некоторые языки имеют «q-значения» - коэффициент относительного качества , от 0 до 1. Более высокие значения q означают, что язык предпочитается клиентом. Отсутствие q-значения действительно является самым высоким q-значением - неявным 1.0
(как в случае en-AU
в приведенной выше строке). Небольшое осложнение - браузер может отправлять вам языки с q-значениями, скажем, 0 - и я понимаю, что вы должны отклонить эти языки, если это возможно.
Анализ заголовка Accept-Language
Имея это в виду, вот несколько различных, но похожих подходов, которые я рассмотрел для разбора такой строки в список языков, упорядоченных по их q-значениям. С простым Ruby:
# to_s to deal with possible nil value, since nil.to_s => ""
langs = request.env['HTTP_ACCEPT_LANGUAGE'].to_s.split(",").map do |lang|
l, q = lang.split(";q=")
[l, (q || '1').to_f]
end
# => [["en-AU", 1.0], ["en-US", 0.7], ["en", 0.3]]
Или, если вы разбираетесь в регулярных выражениях, вы можете достичь того же, что и выше, и, возможно, улучшить мое регулярное выражение одновременно:
rx = /([A-Za-z]{2}(?:-[A-Za-z]{2})?)(?:;q=(1|0?\.[0-9]{1,3}))?/
langs = request.env['HTTP_ACCEPT_LANGUAGE'].to_s.scan(rx).map do |lang, q|
[lang, (q || '1').to_f]
end
В любом случае, при необходимости вы можете выполнить что-то вроде:
# return array of just languages, ordered by q-value
langs.sort_by(&:last).map(&:first).reverse
# => ["en-AU", "en-US", "en"]
Я начал свой анализ с просмотра этой сущности , но в итоге изменил его довольно значительно. Регулярное выражение особенно отбрасывало совершенно хорошие вторичные локали, например, en-AU
стало en
, zh-TW
стало zh
. Я попытался исправить это с помощью моих модификаций этого регулярного выражения.