user2800089
user2800089

Reputation: 2391

Play Framework 2.0 - issue in rendering view

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.

Upvotes: 0

Views: 931

Answers (2)

biesior
biesior

Reputation: 55798

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>

Upvotes: 0

Maxime Dantec
Maxime Dantec

Reputation: 562

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>

Upvotes: 1

Related Questions