简体   繁体   中英

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 . (ie 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. Eg 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM