0

I followed this link https://github.com/julienrf/play-jsmessages/commit/3f67083e296edc039af6ed7fc0fe698a282d01b5 to implement i18N in javascript.

Application.java
===================
package controllers;

import java.util.HashMap;
import java.util.Map;
import play.i18n.Messages;
import play.i18n.Lang;
import play.*;
import play.mvc.*;
import jsmessages.JsMessages;

import views.html.*;

import models.Session;

public class Application extends Controller {

    private static Session session;
    final static JsMessages messages = new JsMessages(play.Play.application());

    /**
     * Loads the application
     * @return
     */
    public static Result index() {
        return load();
    }
    public static Result jsMessages() {
        System.out.println("in jsMessages");
        return ok(messages.generate("window.Messages")).as("application/javascript");
    }

    /**
     * Initial load function, clears all stored session data
     * @return Redirect to homepage.html
     */
    public static Result load() {
        System.out.println("in load1");
        session = new Session();
        changeLang("fr");
        jsMessages();
        return ok(mainpage.render(messages));
    }


    public static Result reset() {
        session = new Session();
        return ok();
    }

    public static Session getSession() {
        if(session == null) {
            session = new Session();
        }
        return session;
    }
}

HTML which is rendered properly if i don't include i18n code for javascripts
mainpage.scala.html
==========================
@(messages: jsmessages.JsMessages)
<html>
<head>
@messages.html("window.Messages")
</head>

//some code goes here

</html>


javascript loaded on rendering homepage.scala.html
Main.js
======
// some code goes here
alert(Messages('first'));
//some code goes here


If I am not including i18n code in Application.java , mainpage.scala.html and main.js , my application is working fine but after including i18n code , page is not getting loaded.

As per my understanding , problem is with rendering ,as two results are being returned from load() and jsMessages().Kindly suggest me how to render both javascript and html or any other way so that this issue can be resolved.

user2800089
  • 2,015
  • 6
  • 26
  • 47

2 Answers2

1

You have to choose between loading 'jsMessages' in a file (route) or display them in a template.

First scenario, then you use:

// Controller:
public static Result jsMessages() {
    System.out.println("in jsMessages");
    return ok(messages.generate("window.Messages")).as("application/javascript");
}

// Route file:
GET     /messages.js                controllers.Application.jsMessages()

// Template:
<script type="text/javascript" src="@routes.Application.jsMessages()"></script>

Second scenario, then remove public static Result jsMessages() and:

// Controller
public static Result load() {
    System.out.println("in load1");
    session = new Session();
    changeLang("fr");
    return ok(mainpage.render(messages.generate("window.Messages")));
}

// Template:
@(messages: String)
<script type="text/javascript">@messages</script>
Maxime Dantec
  • 562
  • 2
  • 11
  • I tried to implement second approach.In my old approach , messages which are returned are of JsMessages type and i am fetching the value of any key in js using alert(Messages('first')); In your second approach , value returned is of String type so how to fetch value of any particular key in js – user2800089 Nov 26 '13 at 07:38
  • I have 1 doubt in your first approach that messages.js in routes file is response of jsMessages() present in controller?? – user2800089 Nov 26 '13 at 12:20
0

Note: That's not a direct answer for your problem, just suggestion for other approach

You don't need to use Play's controllers at all instead you can use pure JS files placed in public assets. Let's say that you have 2 languages, one of them is default (let's assume that's English) in such case all you need to is just declare a object with translated labels and some getter ie:

/public/i18n/messages.js

var messages_default = {
   'save': 'Save',
   'delete': 'Delete',
   'warning': 'You can\'t do that'
}

function jsMessage(key) {
    var translated = messages[key];
    if (typeof translated === "undefined") {
        translated = messages_default[key];
        if (typeof translated === "undefined") {
            translated = key;
        }
    }
    return translated;
}

so you can create a new file for each language and only add translations to it (note: without _default suffix)

/public/i18n/messages_de.js (used Google translator for the 'translations, don't blame me ;)):

var messages = {
    'save': 'Sparen',
    'delete': 'Löschen',
    'warning': 'Sie können nicht tun'
}

in Play's localization file (for non default languages only! conf/messages.de in this case) add a label for path of additional language JS file, ie:

add_i18n = i18n/messages_de.js

So finally you can include it in German version or skip in default lang with simple condition (remember that for non existing labels Play's Messages returns the key)

<script src='@routes.Assets.at("i18n/messages_default.js")'></script>
@if(Messages("add_i18n") != "add_i18n")){
    <script src='@routes.Assets.at(Messages("add_i18n"))'></script>
}

So finally you can use it in JS like:

<script>
    alert( jsMessage('warning') );
</script>
biesior
  • 55,576
  • 10
  • 125
  • 182
  • I followed these steps: 1) Created /public/i18n/messages.js and copied the code mentioned by you . 2) Created /public/i18n/messages_de.js and copied the code 3) Created /conf/messages.de file and added the key value pair. 4) wrote add_i18n = i18n/messages_de.js in application.conf file 5) wrote routes.asset code, mentioned by you, in mainpage.scala.html 6) wrote alert(Messages('save')); in main.js. But its not working.Kindly correct me if i am going wrong anywhere. – user2800089 Nov 26 '13 at 09:10
  • Check my currnet edit for the last snippet of code (with `jsMessage(key)` ) – biesior Nov 26 '13 at 09:13
  • I included the alert message but now its failing on this line var translated = messages[key]; saying messages is not defined – user2800089 Nov 26 '13 at 11:55
  • In my approach , which i asked in question , can we directly get javascript response from jsMessages() to my main.js instead of routing through mainpage.scala.html – user2800089 Nov 26 '13 at 12:36