Play Framework 2.4.0 and I18n with Scala - scala

I have a project with Play Framework 2.3.8 and I'm migrating in Play Framework 2.4 but I have a problem with I18n.
Now I have in a view code like this:
#Messages("components.navbar.text")(locale.MyLang)
where locale is:
object locale {
var MyLang =Lang("it")
def changeLang(newLang:String): Unit ={
MyLang=Lang(newLang)
}
}
I would mantainer this structure without using implicit lang, is possible ?
I have some situation where I use in the same page different language and in this case is difficult and boring with the implicit lang.

If I understand your question correctly, which is that you want to override the user's chosen language for certain blocks of the page, I would do this (for Play 2.4) using an implicit Messages object:
#()(implicit messages: Messages)
<!-- some section in the user's chosen language -->
<h1>#Messages("hello.world")</h1>
<!-- some section in a specific language -->
#defining(messages.copy(lang = play.api.i18n.Lang("it")) { implicit messages =>
<h2>#Messages("something.in.italian")</h2>
}
That is, use defining to create a new (implicit) messages for certain nested blocks of HTML.
If you really wanted to go to town (and I wouldn't necessarily recommend this) you could add an italian method to Messages via an implicit class:
(in my.package.utils.i18n.MessagesExtensions.scala):
package my.packages.utils.i18n
import play.api.i18n.{Lang, Messages}
implicit class MessagesExtensions(messages: Messages) {
def italian = messages.copy(lang = Lang("it"))
// and an `as` method for good measure:
def as(code: String) = messages.copy(lang = Lang(code))
}
To have that work in a view you need to add the class to your templateImport in your build.sbt:
templateImports in Compile ++= Seq(
"my.packages.utils.i18n.MessagesExtensions"
)
Then in your templates you can just to this:
#()(implicit messages: Messages)
<!-- some section in the user's chosen language -->
<h1>#Messages("hello.world")</h1>
<!-- some section in a specific language -->
#defining(messages.italian) { implicit messages =>
<h2>#Messages("something.in.italian")</h2>
....
}
<!-- or singly, in another language -->
<h3>#Messages("another.thing.in.french")(messages.as("fr"))</h3>
But that might be overkill, unless it really saves you a lot of boilerplate language switching.

Related

How to execute tests on the argument that a controller passes to the view in Play Framework

In our play application every controller function fetches data from the database (or some other way) and passes these values to the result
def index = Action { implicit request =>
val newsItems: List[String] = fetchNewsFromDB()
Ok(views.html.home.index(newsItems))
}
def fetchNewsFromDB() = List("Headline1", "Headline2")
I am writing tests using specifiactions (based on the documentation http://www.playframework.com/documentation/2.2.x/ScalaTest)
According to this documentation by controller as follows. In the next test I want to make sure that the index page contains a headline. I do this by checking if there exists a div with the class "headline"
"Example Page#index" should {
"should contain a headline" in {
val controller = new TestController()
val result: Future[SimpleResult] = controller.index().apply(FakeRequest())
val bodyText: String = contentAsString(result)
bodyText.toLowerCase must contain("<div class=\"headline\"")
}
}
However I would rather check whether the list newsItems which the controller passes to the view is nonempty.
What is the best way to do this?
Is it possible to this in a generic way for which little modification of the controllers is required?
I too was frustrated that I couldn't intercept the parameters on their way to the template - and in fact it can become extremely difficult to even get the template to render at all in tests if you have a lot of "state" in your pages (for example, implicits that provide the user object, navigation helpers etc).
What I ended up doing was putting in an extra "seam" for testability in my controllers; in my tests, I extend the controller under test, replacing the HTML rendering function with a mocked one, which I can then use to verify the parameters.
Here's a simple example based on your "news" Action; first, the controller, which is no longer an object so we can extend it:
object Application extends ApplicationController
trait ApplicationController extends Controller {
def newsAction = Action {
Ok(renderNews("this is the news"))
}
def renderNews(s:List[String]):Html = html.sandbox(s)
}
The renderNews method gives us the all-important "test seam". I think it also actually improves the readability of controller methods too, which is nice :-)
Now, the unit test:
class ApplicationSpec extends Specification with Mockito {
val mockedNewsRenderer = mock[List[String] => Html]
val controller = new ApplicationController {
override def renderNews(s:List[String]) = mockedNewsRenderer(s)
}
"Application News Controller" should {
"Pass a non-empty list of news items to the template" in {
val result = controller.newsAction(FakeRequest())
status(result) must beEqualTo(200)
val captor = ArgumentCaptor.forClass(classOf[List[String]])
there was one(mockedNewsRenderer).apply(captor.capture())
val theArgument = captor.getValue
theArgument.isEmpty must beFalse
}
}
}
We create a mock to stand-in for the renderNews function, extend the controller so that we can substitute it in (note that we don't change anything else about it of course), and then call the action as normal. Note that we still get a standard Play Result so we can still check status codes etc, but then, we can use the Mockito verify functionality that's built into Specs2, together with Mockito's ArgumentCaptor facility to assert that our template was indeed called, and that it was supplied with a non-empty list of strings.
This approach has worked well for me - it makes it possible to get really good code coverage of your controllers with fast-running and easy-to-write unit tests.
You have a very good question and a very valid point on testing controllers, but I'm afraid it can't be done easily. The problem is that the views compile to Scala functions meaning when you call views.html.home.index(newsItems) it will return an object of Html, which already has the Html put together and compiled. If you would like to test what get's passed in you need to intercept it before the view is called.
To solve this you would have to rewrite your controllers, by moving all your business logic out of the controller and only have the necessary request handling code there. That would almost be easier to test.

Change language of text in template in play framework 2.1.1

I want the user of the application can change the language in my play2 (play 2.1.1, scala 2.10.1) web application. I use #Messages.get(...) in my templates for i18n.
I have
application.langs="en,ru"
in application.conf. I pass "en" or "ru" to that method:
def index = Action {
Ok(views.html.index())
}
def changeLanguage(lang:String) = Action {
implicit request =>
Logger.logger.debug("Change user lang to : " + lang)
val referrer = request.headers.get(REFERER).getOrElse(HOME_URL)
Redirect(referrer).withLang(Lang(lang))
}
routes:
GET / controllers.Application.index
GET /index controllers.Application.changeLanguage(lang ?= "ru")
the template bunch (views.html.index):
#()(implicit l: Lang)
#import play.i18n.Messages
...
<a href="/about">#Messages.get("about")</li>
...
...
After redirecting the page, I see it on the same language. :(
I was read many old answers: implicit language parameter in my template does not work, redirect or action with withLang(...) method call too. Did not have a good solution so long time?
I made it work, so there are my changes. In app code (without an request instance play does not know where to get the cookie with the language?):
def index = Action {
implicit request=>
Ok(views.html.index())
}
And in the template (play.api.i18n imports automatically):
#()(implicit l: Lang)
...
<a href="/about">#Messages("about")</li>
...
...
I had the same issue and added my own message-resolution class over the play.i18n one.
For message resolution, you can have a example here (in Java): https://github.com/adericbourg/proto-poll/blob/dev/app/util/user/message/Messages.java#L76
And my controller changeLang's method calls this: https://github.com/adericbourg/proto-poll/blob/dev/app/util/security/CurrentUser.java#L71
It do not believe it is a good solution (it requires more code and I'm a lazy guy) but it works. Hope this can help...

Form errors i18n Play framework

I'm using the form helper and a custom form template to render my forms in the Play framework like this:
#(lang: Lang)(myForm: Form[MyModel])
#import play.i18n._
#import helper._
#implicitField = #{ FieldConstructor(formTemplate.f) }
#form ( action = routes.Application.index() ){
#inputText(
field = myForm("username"),
'_label -> Messages.get(lang, "username")
)
}
When the template is called with different values for lang, the label is displayed in the respective language.
However, when the form is submitted, error messages are always displayed in the main language. (i.e. for Required fields it's always This field is required.)
As the answer to this post mentioned, I changed the default error messages like so in my language files (currently only 2):
messages.en:
username=Username
error.required=This field is required
messages.nl:
username=Gebruikersnaam
error.required=Dit veld is verplicht
How can I make sure the errors are printed in the correct language?
I've already tried doing the following in my custom template, but without success:
#(elements: helper.FieldElements)
<!-- snipped some HTML code -->
<span class="help">
#(elements.infos(elements.args.get('_lang) match {
case Some(language) => language.asInstanceOf[play.api.i18n.Lang]
case None => new Lang("en","uk")
}).mkString(", "))
</span>
And by adding '_lang -> lang to my #inputText call.
I'm used to programming in Java and have only done some Scala in the Play templates. I'm using Play 2.0.4.
I have found the easiest way of doing this (note: I program in Java) is by defining a static method in one of your models that returns the users language:
public class User{
import play.i18n.Lang;
//simplified
public static Lang getLanguage(){
if(session("language" != null){
return Lang.forCode(session.get("language"));
} else {
return Lang.forCode("en"); //default language
}
}
You can then call this static function in your Scala form template like this:
<span class="errors">#elements.errors(User.getLanguage()).mkString(", ")</span>
to display translated errors based on the default error messages in your messages.xx files.
As a general matter, if your error codes are also found in the messages.xx resource files, they get localized, even if you program a custom validator somewhere else. You don't have to have the Lang in scope or call Messages() yourself. E.g. in Scala Play:
val validPhone = """\+?[0-9_\-\. \(\)]*$""".r
val phoneCheckConstraint: Constraint[String] = Constraint("constraints.phonecheck")({
plainText =>
val errors = plainText match {
case validPhone() => Nil
case _ => Seq(ValidationError("error.phonenumber"))
}
if (errors.isEmpty) {
Valid
} else {
Invalid(errors)
}
})
If you merely have
error.phonenumber=Invalid phone number
in your messages.en file and translated versions in other messages.xx files they will get localized by Play even though no Lang was in scope at the point of declaration. So no need to pass Lang around other than in your templates and elsewhere for explicit Messages() calls.

Scala drivers for couchdb and partial schemas

One question I have about current Scala couchdb drivers is whether they can work with "partial" schemas". I'll try to explain what I mean: the libraries I've see seem to all want to do a complete conversion from JSON docs in the database to a Scala object, handle the Scala object, and convert it back to JSON. This is is fine if your application knows everything about that type of object --- especially if it is the sole piece of software interacting with that database. However, what if I want to write a little application that only knows about part of the JSON object: for example, what if I'm only interested in a 'mybook' component embedded like this:
{
_id: "0ea56a7ec317138700743cdb740f555a",
_rev: "2-3e15c3acfc3936abf10ea4f84a0aeced",
type: "user",
profiles: {
mybook: {
key: "AGW45HWH",
secret: "g4juh43ui9hg929gk4"
},
.. 6 or 7 other profiles
},
.. lots of other stuff
}
I really don't want to convert the whole JSON AST to a Scala object. On the other hand, in couchdb, you must save back the entire JSON doc, so this needs to be preserved somehow. I think what I really what is something like this:
class MyBook {
private val userJson: JObject = ... // full JSON retrieved from the database
lazy val _id: String = ... // parsed from the JSON
lazy val _rev: String = ... // parsed from the JSON
lazy val key: String = ... // parsed from the JSON
lazy val secret: String = ... // (ditto)
def withSecret(secret: String): MyBook = ... // new object with altered userJson
def save(db: CouchDB) = ... // save userJson back to couchdb
}
Advantages:
computationally cheaper to extract only needed fields
don't have to sync with database evolution except for 'mybook' part
more suitable for development with partial schemas
safer, because there is less change as inadvertently deleting fields if we didn't keep up with the database schema
Disadavantages:
domain objects in Scala are not pristinely independent of couch/JSON
more memory use per object
Is this possible with any of the current Scala drivers? With either of scouchdb or the new Sohva library, it seems not.
As long as you have a good JSON library and a good HTTP client library, implementing a schemaless CouchDB client library is really easy.
Here is an example in Java: code, tests.
My couchDB library uses spray-json for (de)serialization, which is very flexible and would enable you to ignore parts of a document but still save it. Let's look at a simplified example:
Say we have a document like this
{
dontcare: {
...
},
important: "foo"
}
Then you could declare a class to hold information from this document and define how the conversion is done:
case class Dummy(js:JsValue)
case class PartialDoc(dontcare: Dummy, important: String)
implicit object DummyFormat extends JsonFormat[Dummy] {
override def read(js:JsValue):Dummy = Dummy(js)
override def write(d:Dummy):JsValue = d.js
}
implicit val productFormat = jsonFormat2(PartialDoc)
This will ignore anything in dontcare but still safe it as a raw JSON AST. Of course this example is not as complex as the one in your question, but it should give you an idea how to solve your problem.

Finite State Machine and inter-FSM signaling

Recommendations for languages with native (so no FSM generation tools) support for state machine development and execution and passing of messages/signals. This is for telecoms, e.g implementation of FSMs of this level of complexity.
I have considered Erlang, but would love some feedback, suggestions, pointer to tutorials, alternatives, particularly Java based frameworks. Maybe Scala?
Open source only. I'm not looking for UML or regular expression related solutions.
As this is for the implementation of telecoms protocols the FSMs may be non-trivial. Many states, many transitions, signal based, input constraints/guards. Dynamic instantiation would be a plus. Switch statements are out of the question, it quickly nests to unusable. It's barely better that if/else.
I would prefer to not depend on graphical design; the format FSM description should be human readable/editable/manageable.
--
I have decided to focus on an Actor based solution for C++
For example, the Theron framework provides a starting point http://theron.ashtonmason.net/ and to avoid switch statements in the FSM based event handler this C++ FSM Template Framework looks useful http://satsky.spb.ru/articles/fsm/fsmEng.php
This particular application, telco protocol implementation, is what Erlang was built for. The initial applications of Erlang at Ericsson were telephone switches and the earliest commercial products were ATM switches supporting all manner of telco protocols.
OTP has a standard behaviour for implementing FSMs called gen_fsm. There's an example of its use in a non-trivial FSM in some of the OTP Documentation.
OSERL is an open souce SMPP implementation in Erlang and demonstrates how you can implement a telco protocol using gen_fsms. A good example to look at would be gen_esme_session.
While I can't point you to the code, I know there are quite a few Erlang companies selling telco oriented products: Corelatus, Synapse, Motivity among others.
I agree that switch statements should be out of the question... they eventually lead to maintenance nightmares. Can't you use the State Pattern to implement your FSM? Depending on your actual implementation, you could use actors (if you have multiple FSM collaborating - hm... is that possible?). The nice thing about actors is that the framework for passing messages is already there.
An example of using State would be:
trait State {
def changeState(message: Any): State
}
trait FSM extends Actor {
var state: State
def processMessage(message: Any) {
state = state.changeState(message)
}
override def act() {
loop {
react {
case m: Any => processMessage(m)
}
}
}
}
This is very basic code, but as I don't know more of the requirements, that's the most I can think of. The advantage of State is that every state is self-contained in one class.
I disagree that FSM are trivial to implement. This is very short-sighted, and shows either a lack of familiarity with the alternatives, or the lack of experience with complex state machines.
The fundamental problem is that a state machine graph is obvious, but FSM code is not. Once you get beyond a dozen states and a score of transitions, FSM code becomes ugly and difficult to follow.
There are tools whereby you draw the state machine, and generate Java code for it. I don't know of any open source tools for that, however.
Now, getting back to Erlang/Scala, Scala has Actors and message passing as well, and is based on the JVM, so it might be a better alternative than Erlang given your constraints.
There's a DFA/NFA library on Scala as well, though it is not particularly a good one. It supports conversion from arbitrary regular expressions (ie, the literals need not be characters) into DFA/NFA.
I'll post some code below using it. In this code, the idea is creating a FSM which will accept any sequential combination of arbitrary prefixes for a list of words, the idea being looking up menu options without predefined keybinds.
import scala.util.regexp._
import scala.util.automata._
// The goal of this object below is to create a class, MyChar, which will
// be the domain of the tokens used for transitions in the DFA. They could
// be integers, enumerations or even a set of case classes and objects. For
// this particular code, it's just Char.
object MyLang extends WordExp {
type _regexpT = RegExp
type _labelT = MyChar
case class MyChar(c:Char) extends Label
}
// We now need to import the types we defined, as well as any classes we
// created extending Label.
import MyLang._
// We also need an instance (singleton, in this case) of WordBerrySethi,
// which will convert the regular expression into an automatum. Notice the
// language being used is MyLang.
object MyBerrySethi extends WordBerrySethi {
override val lang = MyLang
}
// Last, a function which takes an input in the language we defined,
// and traverses the DFA, returning whether we are at a sink state or
// not. For other uses it will probably make more sense to test against
// both sink states and final states.
def matchDet(pat: DetWordAutom[MyChar], seq: Seq[Char]): Boolean =
!pat.isSink((0 /: seq) ((state, c) => pat.next(state, MyChar(c))))
// This converts a regular expression to a DFA, with using an intermediary NFA
def compile(pat: MyLang._regexpT) =
new SubsetConstruction(MyBerrySethi.automatonFrom(pat, 100000)).determinize
// Defines a "?" function, since it isn't provided by the library
def Quest(rs: _regexpT*) = Alt(Eps, Sequ(rs: _*)) // Quest(pat) = Eps|pat = (pat)?
// And now, the algorithm proper. It splits the string into words
// converts each character into Letter[MyChar[Char]],
// produce the regular expression desired for each word using Quest and Sequ,
// then the final regular expression by using Sequ with each subexpression.
def words(s : String) = s.split("\\W+")
def wordToRegex(w : String) : Seq[MyLang._regexpT] = w.map(c => Letter(MyChar(c)))
def wordRegex(w : String) = Quest(wordToRegex(w) reduceRight ((a,b) => Sequ(a, Quest(b))))
def phraseRegex(s : String) = Sequ(words(s).map(w => wordRegex(w)) : _*)
// This takes a list of strings, produce a DFA for each, and returns a list of
// of tuples formed by DFA and string.
def regexList(l : List[String]) = l.map(s => compile(phraseRegex(s)) -> s)
// The main function takes a list of strings, and returns a function that will
// traverse each DFA, and return all strings associated with DFAs that did not
// end up in a sink state.
def regexSearcher(l : List[String]) = {
val r = regexList(l)
(s : String) => r.filter(t => matchDet(t._1, s)).map(_._2)
}
I can hardly think of any language where implementing an FSM is non-trivial. Maybe this one.
...
if (currentState == STATE0 && event == EVENT0) return STATE1;
if (currentState == STATE1 && event == EVENT0) return STATE2;
...
The State pattern (using Java enums) is what we use in our telecom application, however we use small FSM's:
public class Controller{
private State itsState = State.IDLE;
public void setState(State aState){
itsState = aState;
}
public void action1(){
itsState.action1(this);
}
public void action2(){
itsState.action2(this);
}
public void doAction1(){
// code
}
public void doAction2(){
// code
}
}
public enum State{
IDLE{
#Override
public void action1(Controller aCtx){
aCtx.doAction1();
aCtx.setState(State.STATE1);
}
},
STATE1{
#Override
public void action2(Controller aCtx){
aCtx.doAction2();
aCtx.setState(State.IDLE);
}
},
public void action1(Controller aCtx){
throw new IllegalStateException();
}
public void action2(Controller aCtx){
throw new IllegalStateException();
}
}
FSM should be trivial to implement in any language that has a case statement.Your choice of language should be based on what that finite state machine needs to do.
For example, you state that you need to do this for telecom development and mention messages. I would look at systems/languages that support distributed message passing. Erlang does this, and I"m sure just about every other common language supports this through an API/library for the language.