I use Play 2.5.6 with Scala and found several interesting modules but I think some basic and really useful features are still missing...
Here is my sample app where I do my tests :
I list here needed features (according to me) from the most needed to the least needed.
MessagesApi
use the browser Accept-Language
to choose language which is really nice :)
But sometimes I want to give to the user the possibility to change the language of the application and I couldn't figure out how...
Maybe I just lack of knowledge but none of my google search did help.
I often have text like : "no results", "1 result", "5 results" and it doesn't seem to exist a convenient way to do it in Play templates. The naive approach is quite verbose and needs 3 keys :
results.0=no results
results.1=1 result
results.n={0} results
@results.length match {
case 0 => { @message("results.0") }
case 1 => { @message("results.1") }
case _ => { @message("results.n", results.length) }
}
So I've done two helpers (depending on the needed flexibility) based on this convention to minimize template code :
object I18nHelper {
def plural(count: Int): String = count match {
case 0 => ".0"
case 1 => ".1"
case _ => ".n"
}
def messagePlural(key: String, count: Int)(implicit lang: Lang, message: MessagesApi): String = count match {
case 0 => message(key + ".0")
case 1 => message(key + ".1")
case _ => message(key + ".n", count)
}
}
@import global.helpers.I18nHelper._
@message("results"+plural(results.length), results.length)
@messagePlural("results", results.length)
I find it better as there is a "clear" convention and the code template holds in one line but it's just a workaround. To me, the solution of angular translate is quite nice :
results={$0, plural, =0{no results} one{1 result} other{# results}}
@message("results", results.length)
I love Scala and Play partly because of the type safety they provide. But when it comes to i18n, it's just like any JavaScript unsafe code :( How to be sure that all my keys are declared on all languages ? And used with correct parameters (number & type) ?
If I forgot to declare a key, there is no error, the key is simply printed on screen (who want that ?)
It's the same when I forget a parameter, no error, the {0}
is simply printed out (again, who want that ?)
In the same way, if I define a key twice, it is simply overridden silently, which could be hard to troubleshoot...
Moreover, I don't want to write test for all of these errors... So I can ship some of them in my code :(
I saw e2e and play-messagescompiler but I didn't test them yet and I think it should be the default behavior of Play build. It's quite cumbersome to find, learn & install many plugins (more or less mature/maintained)
Having named parameters (just like html input helpers) and having the possibility to pass objects and access some property could be a great improvement for clarity :
page_result=results {1} to {2} on {3}
@message("page_result", page.start, page.end, page.total)
vs
page_result=results {page.start} to {page.end} on {page.total}
@message("page_result", 'page -> page)
Dealing with date formatting is always tough. Personally I define many standards formatting for each language :
date=dd/MM/yyyy
date.l=d/M/yyyy
date.L=dd/MM/yyyy
date.ll=d MMM yyyy
date.LL=d MMMM yyyy
date.lll=EE d MMM yyyy
date.LLL=EEEE d MMMM yyyy
time=HH:mm
time.t=H:mm
time.T=HH:mm
time.tt=H:mm:ss
time.TT=HH:mm:ss
datetime=dd/MM/yyyy HH:mm
datetime.lt=d/M/yyyy H:mm
datetime.LT=dd/MM/yyyy HH:mm
datetime.ltt=d/M/yyyy H:mm:ss
datetime.LTT=dd/MM/yyyy HH:mm:ss
text_with_date=Today we are on {0}
object I18nHelper {
def date(date: DateTime, suffix: String = "L")(implicit lang: Lang, message: MessagesApi): String = {
date.toString(message("date." + suffix), lang.toLocale)
}
}
@message("text_with_date", I18nHelper.date(new DateTime()))
It would be nice if I could re-use some values, ex :
date=dd/MM/yyyy
time=HH:mm
datetime={date} {time}
I don't have a great solution for dates (yet) but I think it could be worth thinking about it.
Now, the result of the @message
is a string which is escaped but splitting text not to include html tags could be cumbersome (ex: <a>, <b>, <i>, <span>)
So, I use the workaround :
pages.index.sample.twitt=Follow <a href="https://twitter.com/{0}" target="_blank">{0}</a> on Twitter
@Html(message("pages.index.sample.twitt", "conferencelist_"))
But I don't know if it's the intended usage...
These are more nice-to-have but it would be nice to be able to use nested keys (like in hocon) and split keys in multiple files (like with foldermessages)