18장
URI기반의 로케일 선택(URI-based locale selection)
18.1 문제점
나는 Lift를 평가하고 있고 내가 놓친(또는 어떻게 구현하는지 볼수 없었던) 한가지는 URI패턴으로부터 로케일을 결정하는 능력입니다.
namespace="/{request_locale}"
그래서 URI=/no/companies/company/1에서 호출된 (REST풀한)액션을 가질 수 있고 id=1와 no로 설정되는 로케일(locale)을 가진 CompanyAction을 호출할 것입니다. 만약 URI=/en/companies/company/1로부터 호출되었다면 같은 CompanyAction을 호출할 것지지만 로케일은 “en”으로 설정될 것입니다.
그래서 내 질문은 다음과 같을 것입니다: /{request_locale} 부분 뒤의 *.xhtml을 해결하려고 시도하기 위해서 Lift가 어떤 uri패턴에 기반해서 로케일을 획득하도록 가르치는 것이 가능한가?
/no/index.xhtml
/en/index.xhtml
그러면 다른 로케일은 가진 같은 템플릿을 매핑할 것입니다.
18.2 해결책
이것은 URL 재작성의 이상적인 사용입니다.
Boot.scala에서 모듈을 UrlLocalizer.init()와 연결해야 합니다.
DPP’s GitHub Starting Point에서 완전히 동작하는 예제를 볼 수 있습니다.
여기 코드가 있습니다.
package code
package lib
import net.liftweb._
import http._
import provider._
import common._
import java.util.Locale
object UrlLocalizer {
// 예전의 지역화 함수를 획득합니다
val oldLocalizeFunc = LiftRules.localeCalculator
/**
* 이용가능한 로케일은 무엇입니까?
*/
val locales: Map[String, Locale] = Map(Locale.getAvailableLocales.map(l => l.toString -> l) :_*)
object currentLocale extends RequestVar(Locale.getDefault)
/**
* 로케일을 추출합니다
*/
def unapply(in: String): Option[Locale] =
if (currentLocale.set_?) None // 중복하지 마세요
else locales.get(in) // 유효한 로케일이라면 매칭됩니다
/**
* 로케일을 계산합니다
*/
def calcLocale(in: Box[HTTPRequest]): Locale =
if (currentLocale.set_?) currentLocale.get
else oldLocalizeFunc(in)
/**
* 로케일을 초기화합니다
*/
def init() {
// Lift를 후킹합니다
LiftRules.localeCalculator = calcLocale
// 경로의 헤드에서 로케일을 가진 요청을 재작성합니다
LiftRules.statelessRewrite.append {
case RewriteRequest(ParsePath(UrlLocalizer(locale) :: rest, _, _, _), _, _) => {
currentLocale.set(locale)
RewriteResponse(rest)
}
}
}
}
Comments