4

С новой версией 2.4/2.5 Play Framework они продвигались дальше, вводя все и удаляя состояние серверов. play.Play.application() теперь устарел. Однако мне нужно приложение в моем шаблоне (например, чтобы все поддерживаемые языки отображались на всех страницах с помощью play.i18n.Lang.availables(play.Play.application())).Как добавить приложение в шаблон платформы Play Framework 2.5

Я знаю, что мог:

  • Pass play.Application явно все мои шаблоны.
  • Добавьте неявный параметр в мой шаблон, например @()(implicit app: play.Application). Однако в моем Java-проекте это не совсем неявно, я должен передавать его каждый раз, когда я создаю шаблон.
  • Create a Scala object providing the application implicitly. Однако это также требует устаревшего play.api.Play.current.

Как я могу ввести play.Application в мой шаблон?

---- Обновление: ----

То, что я пытался до сих пор, я создал следующие настройки:

index.scala.html:

@(title: String) 
@template(title) { //here is the play.Application obviously missing, however I don't want to pass it in every template - even worse in every Controller <-- this is the core of my question 
    Welcome to my page! 
} 

template.scala.html:

@(title: String)(content: Html)(implicit app: play.Application) 
<html> 
    <head> 
     <title>@title</title> 
    </head> 
    <body> 
     <p>Is live? @app.isProd</p> 
     @content 
    </body> 
</html> 

функции контроллера:

public Result index() { 
    return ok(views.html.index.render("home")); 
} 
+0

Что вам нужно делать с игрой. Применение? –

+0

Я хотел бы перечислить все доступные Langs как 'new play.api.i18n.DefaultLangs (play.Play.application().configuration()). availables() 'для отображения языкового переключателя. – Itchy

+0

Я поставил ответ как ваше требование. Если вы столкнетесь с какой-либо проблемой, сообщите мне об этом. :) –

ответ

1

Мне просто нужно было изучить это для платформы Play 2.6.x. Можно вставить объект в шаблон в соответствии с документацией: https://www.playframework.com/documentation/2.6.x/ScalaTemplatesDependencyInjection.

я реализовал простой образец (немного изобретенным), и я использовал:

Scala

test.scala.html:

@this(configuration: play.api.Configuration) 
@(key: String) 
config = @configuration.get[Seq[String]](key).mkString(", ") 

HomeController.scala

package controllers 

import javax.inject._ 

import play.api._ 
import play.api.i18n._ 
import play.api.mvc._ 

/** 
* This controller creates an `Action` to handle HTTP requests to the 
* application's home page. 
*/ 
@Singleton 
class HomeController @Inject()(cc: ControllerComponents, testView: views.html.test) (implicit configuration: Configuration) extends AbstractController(cc) with I18nSupport{ 

    def test() = Action { implicit request => 
    Ok(testView("play.i18n.langs")) 
    } 
} 

маршруты:

GET  /test    controllers.HomeController.test() 

T его объект конфигурации вводится в шаблон views.html.test, и сам вид вводится в контроллер. Обратите внимание на инструкцию @this(configuration: play.api.Configuration) в шаблоне. Play будет генерировать класс за шаблоном с помощью конструктора, который вводит объект Configuration.

Обратите внимание, что введенная конфигурация в контроллер не играет никакой роли в этом конкретном коде. Я экспериментировал с другими перестановками, прежде чем нашел это решение ... Предположим, что если у вас есть внутренний шаблон, используемый внешним шаблоном, который вызывается из контроллера, а внутреннему шаблону нужен объект конфигурации, вам необходимо передать конфигурацию с вершины контроллера вниз и добавьте параметр implicit configuration: play.api.Configuration во все шаблоны в пути иерархии прямо к нужному ему шаблону, примерно так: @(message: String)(implicit messagesProvider: MessagesProvider, configuration: play.api.Configuration) . Затем конфигурация, вводимая контроллером, подается в верхний шаблон полностью к требуемому шаблону.

1

Вы можете получить приложение с Play.current() или впрыскивать приложение в контроллере, как это объясняется в этом question. Шаблон должен получить аргумент типа play.Application.

Это должно быть примерно так.

шаблон, скажем, это injectappexample.scala.html:

@(app: play.Application) 
.... use the app object 

Контроллер:

public class SomeController extends Controller { 
    Provider<Application> applicationProvider; 

    @Inject 
    public SomeController(Provider<Application> applicationProvider) { 
     this.applicationProvider = applicationProvider; 
    } 

    public Result injectAppExample() { 
     return ok(injectappexample.render(applicationProvider.get()); 
    } 
} 

Он стоит пересмотреть отправки объект приложения к шаблону. Если вы должны отправить определенное значение свойства конфигурации, введите Конфигурация в контроллер, получите значение из объекта конфигурации и отправьте его в шаблон. В этом случае инъекция приложения вообще не нужна.

Шаблон:

@(value: String) 
.... use the value 

Контроллер:

public class SomeController extends Controller { 
    Configuration configuration; 

    @Inject 
    public SomeController(Configuration configuration) { 
     this.configuration = configuration; 
    } 

    public Result injectAppExample() { 
     return ok(injectappexample.render(configuration.getString("SOME_PROPERTY")); 
    } 
} 
+0

Спасибо за ваш ответ, однако 'Play.current()' также устарел в Play 2.5, и я хотел бы добавить его в ** шаблоны **, а не в контроллер (как вводить в контроллер ясный и хорошо документированный здесь https://www.playframework.com/documentation/2.5.x/JavaDependencyInjection) – Itchy

+0

Я обновил ответ - надеюсь, это поможет. – asch

0

Это, как правило, не рекомендуется вводить само приложение, потому что это делает ваш код очень громоздким для тестирования. Вместо этого подумайте о том, что вам на самом деле нужно, и прямо вставьте это.

Если у вас есть несколько вещей, в которых вы нуждаетесь почти в каждом шаблоне, моим предложением было бы создать какой-то класс контекста, который вы можете ввести в свой контроллер, а затем передать его шаблону.

+0

Спасибо за ваш ответ, не могли бы вы объяснить, как «вставить это прямо»? Я не понял, как вообще вводить что-либо в шаблон, без необходимости передавать его каждый раз, когда я создаю шаблон в своем Java-коде. – Itchy

+1

Нет, вот что я имел в виду - вам все равно нужно передать этот контекстный объект явно в шаблон каждый раз, когда вы используете шаблон. – rethab

0

Прежде всего, если вы спрашиваете, как внедрить приложение, что вам действительно нужно, это конфигурация.

Вы можете сделать что-то подобное в игре 2.5. Я покажу вам инъекцию конструктора, вы можете использовать полевую инъекцию в качестве своего требования.

import com.google.inject.Inject; 
import play.Configuration; 

public class MyClass{ 
    private Configuration conf; 

    @Inject 
    public MyClass(Configuration conf){ 
     this.conf = conf; 
    } 

} 

Теперь у вас есть свой класс конфигурации. Затем, специально для вашего требования, размещенного в вашем комментарии, вы можете это сделать.

List<Object> langList = conf.getList("play.i18n.langs"); 
//conf.getList("") returns an object array. 
//You can cast to Strings (assuming you are using Java8). 

List<String> languages = new ArrayList<>(langList.size()); 
for (Object object : langList) { 
    languages.add(Objects.toString(object, null)); 
} 

Теперь вы можете иметь свой список языков в languages.