Воспроизвести языковой код Framework 2 в концепции URL?

Руководство по i18n короткое: https://www.playframework.com/documentation/2.4.x/ScalaI18N Есть ли что-нибудь еще, объясняющее концепцию обработки выбора языка пользователем?

Чего я хотел бы достичь, так это того, что делают многие другие сайты: помещать код языка в URL

И затем при вызове (Java) Lang.defaultLang().language() или из шаблона Scala @lang.language я хотел бы получить это значение. Конечно при обычном разрешении, он должен быть в application.conf play.i18n.langs = [ "en","de" ]

Мне действительно нужно прочитать его с URL-адреса самостоятельно?

Кроме того, в файле маршрутов нет ли уже концепции для его непосредственного сопоставления с разрешением языка?

Альтернативой является:

  1. продублируйте все маршруты в файле маршрутов для каждого языка или используйте регулярное выражение для языкового кода
  2. в каждом контроллере вызовите метод для установки языка

person Adrian Pop    schedule 23.09.2015    source источник


Ответы (1)


Вы можете реализовать собственный обработчик запросов и разрешать язык для каждого запроса. Это та же идея, что и ваш "в каждом контроллере вызывать метод для установки языка" но код нужно писать только в одном месте - legacy GlobalSettings.onRequest или new HttpRequestHandler.createAction

Существует очень хорошее описание реализации i18n в игре, основанное на части URL, единственное - это для 2.0.4, так что я полагаю, что вы должны использовать HttpRequestHandler.createAction, но GlobalSettings.onRequest.

Руководство: http://www.flowstopper.org/2013/01/i18n-play-framework-java-app-website.html

Руководство по миграции: https://www.playframework.com/documentation/2.4.x/GlobalSettings< /а>

Пользовательские обработчики запросов: https://www.playframework.com/documentation/2.4.x/JavaHttpRequestHandlers

Живые примеры из моего проекта (Play 2.4.3, Java)

application.conf

play.i18n.langs = [ "en", "de", "fr", "ua" ]
play.http.requestHandler = "plugins.RequestHandler"

маршруты

# Home page
GET     /$lang<[a-z]{2}>/home       controllers.Application.home(lang:String)

плагины/RequestHandler.java

package plugins;

import play.http.DefaultHttpRequestHandler;
import play.libs.F;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.lang.reflect.Method;

public class RequestHandler extends DefaultHttpRequestHandler {

    @Override
    public Action createAction(Http.Request request, Method actionMethod) {
        return new Action.Simple() {
            @Override
            public F.Promise<Result> call(Http.Context ctx) throws Throwable {
                Path path = Paths.get(ctx.request().path());
                String lang = path.getName(0).toString();
                // we detect language only by URL path, cookies does not used 
                ctx.setTransientLang(lang);
                return delegate.call(ctx);
            }
        };
    }
}

контроллеры/Application.java

package controllers;

import play.*;
import play.mvc.*;
import play.i18n.Lang;

import views.html.*;

public class Application extends Controller {

    public Result home(String lang){
       return ok(ctx().lang().code());
    }

}

Это приложение даст результаты

http://localhost:9000/de/home -> "de"

http://localhost:9000/en/home -> "en"

http://localhost:9000/dk/home -> "исключение: Язык не поддерживается в этом приложении: Lang(dk,) не в Lang.availables()"

Обратите внимание: Lang.defaultLang().language() не возвращает текущий язык запроса. Вам нужно вызвать ctx().lang() для возврата текущего языка запроса.

person Andriy Kuba    schedule 23.09.2015
comment
Здравствуйте, спасибо за ответ! Также я должен отметить, что вызов ctx().lang().code() и параметр lang возвращают одно и то же, поэтому я думаю, что можно использовать любой из них. - person Adrian Pop; 16.11.2015