From f32fee941f2757d3b7f8351b0399e33d72a79c4d Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Fri, 26 Jul 2013 23:40:46 +0200 Subject: [PATCH] propose language fallbacks --- app/templating/I18hHelper.scala | 26 +++++++++++++++++++------- app/views/base/layout.scala.html | 6 +++++- modules/i18n/src/main/I18nPool.scala | 10 +++++++--- public/javascripts/big.js | 3 ++- public/stylesheets/common.css | 5 +++++ 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/app/templating/I18hHelper.scala b/app/templating/I18hHelper.scala index f05c4765e4..50bd89537f 100644 --- a/app/templating/I18hHelper.scala +++ b/app/templating/I18hHelper.scala @@ -1,15 +1,15 @@ package lila.app package templating +import scala.util.Random.shuffle + import controllers._ -import lila.user.Context import lila.i18n.Env.{ current ⇒ i18nEnv } import lila.i18n.{ LangList, I18nDomain } - +import lila.user.Context import play.api.i18n.Lang -import play.api.templates.Html import play.api.mvc.{ RequestHeader, Call } -import scala.util.Random.shuffle +import play.api.templates.Html trait I18nHelper { @@ -38,7 +38,7 @@ trait I18nHelper { def langLinks(lang: Lang)(implicit ctx: Context) = Html { langLinksCache.getOrElseUpdate(lang.language, { - pool.names.toList sortBy (_._1) collect { + pool.names.toList sortBy (_._1) map { case (code, name) ⇒ """
  • %s
  • """.format( code, langUrl(Lang(code))(I18nDomain(ctx.req.domain)), @@ -48,11 +48,23 @@ trait I18nHelper { }).replace(uriPlaceholder, ctx.req.uri) } + def langFallbackLinks(implicit ctx: Context) = Html { + { + pool.preferredNames(ctx.req, 3) map { + case (code, name) ⇒ """%s""".format( + code, langUrl(Lang(code))(I18nDomain(ctx.req.domain)), name) + } mkString "" + }.replace(uriPlaceholder, ctx.req.uri) + } + def commonDomain(implicit ctx: Context): String = I18nDomain(ctx.req.domain).commonDomain - def acceptLanguages(implicit ctx: Context): String = - ctx.req.acceptLanguages.map(_.language).distinct mkString "," + def acceptLanguages(implicit ctx: Context): List[String] = + ctx.req.acceptLanguages.map(_.language.toString).toList.distinct + + def acceptsLanguage(lang: Lang)(implicit ctx: Context): Boolean = + ctx.req.acceptLanguages exists (_.language == lang.language) private val uriPlaceholder = "[URI]" diff --git a/app/views/base/layout.scala.html b/app/views/base/layout.scala.html index 258dade18b..2509bbfd43 100644 --- a/app/views/base/layout.scala.html +++ b/app/views/base/layout.scala.html @@ -32,7 +32,7 @@ themepicker: Boolean = false)(body: Html)(implicit ctx: Context) data-sound-file="@routes.Assets.at("sound/alert.ogg")" data-troll="@ctx.troll.toString" data-port="@netPort" -data-accept-languages="@acceptLanguages"> +data-accept-languages="@acceptLanguages.mkString(",")">
    @trans.freeOnlineChessGamePlayChessNowInACleanInterfaceNoRegistrationNoAdsNoPluginRequiredPlayChessWithComputerFriendsOrRandomOpponents()
    @@ -102,7 +102,11 @@ data-accept-languages="@acceptLanguages"> lichess.org + @if(acceptsLanguage(lang)) { @baseline + } else { + @langFallbackLinks + } @menu.map { side =>
    @side
    diff --git a/modules/i18n/src/main/I18nPool.scala b/modules/i18n/src/main/I18nPool.scala index 91ad48774f..c52946f3c9 100644 --- a/modules/i18n/src/main/I18nPool.scala +++ b/modules/i18n/src/main/I18nPool.scala @@ -9,15 +9,19 @@ private[i18n] case class I18nPool(val langs: Set[Lang], val default: Lang) { def nonDefaultLangs = langs - default - val names: Map[String, String] = langs map { l ⇒ - l.language -> LangList.nameOrCode(l.language) - } toMap + val names: Map[String, String] = (langs map langNames).toMap + + private def langNames(lang: Lang): (String, String) = + lang.language -> LangList.nameOrCode(lang.language) def lang(req: RequestHeader) = domainLang(req) | default def preferred(req: RequestHeader) = (req.acceptLanguages find langs.contains) | default + def preferredNames(req: RequestHeader, nb: Int): Seq[(String, String)] = + req.acceptLanguages filter langs.contains take nb map langNames + def domainLang(req: RequestHeader) = cache.getOrElseUpdate(req.domain, { I18nDomain(req.domain).lang filter langs.contains diff --git a/public/javascripts/big.js b/public/javascripts/big.js index ede863d8fb..4aa1fea799 100644 --- a/public/javascripts/big.js +++ b/public/javascripts/big.js @@ -602,9 +602,10 @@ var storage = { }); }); + var acceptLanguages = $('body').data('accept-languages').split(','); $('#top .lichess_language').one('mouseover', function() { var $t = $(this); - _.each($('body').data('accept-languages').split(','), function(lang) { + _.each(acceptLanguages, function(lang) { $t.find('a[lang="' + lang + '"]').addClass('accepted'); }); }); diff --git a/public/stylesheets/common.css b/public/stylesheets/common.css index 6b019ceadb..ef24872d33 100644 --- a/public/stylesheets/common.css +++ b/public/stylesheets/common.css @@ -362,6 +362,11 @@ body.tight #site_header { #site_header strong { font-weight: normal; } +#site_header a.lang_fallback { + font-weight: bold; + display: inline-block; + margin-right: 1em; +} body > div.content { width: 1005px; min-height: 590px;