Play Framework 2.4 use injected variable in Scala template
Asked Answered
A

1

1

I would like to show some data from the database in the menubar of my web page. To get the data, I have a data-access-object (DAO) which is usually created with Guice injection.

How can I use such an (injected) object in my Scala templates?

I could pass it as a parameter to the template, but I had to do this on every single page (because it should be displayed in the menubar). I'm looking for another solution where I don't have to pass it everywhere. Currently I'm creating a new object inside the template, whenever it is rendered (which gets me a cleaner code but a worse performance).

Abmho answered 4/10, 2015 at 14:44 Comment(4)
I don't think there is a straightforward way to achieve what you want, but I think the answers here can help.Burnout
Can you abstract menubar in a separate template to avoid passing the parameter in every template?Nickolai
@BhashitParikh: Thanks for the link, it indeed is a viable option. However, still not one I wished for.Abmho
@Adi: My menubar template is already in a separate template. However I'm calling it from all other templates and so had to provide the parameters via them nevertheless.Abmho
I
3

You can kinda-sorta fake this without too much effort.

First, create a Scala object that provides access to your DAO (this can contain as many things as you want, just repeat the pattern within the top-level object and the Implicits object).

package com.example.stuff

object ViewAccessPoint {
  private[stuff] val myDaoCache = Application.instanceCache[MyDao]

  object Implicits {
    implicit def myDao(implicit application: Application): MyDao = myDaoCache(application)
  }
}

In your view, you can then import the Implicits object into your template and get hold of the DAO created by Guice.

@import com.example.stuff.ViewAccessPoint.Implicits._
@import play.api.Play.current

myDao.whatever()

This works for both Java and Scala projects.

You can see this in practice here:

On a side note, I would consider if you really want to be doing data access in your template layer.

Irrefrangible answered 6/10, 2015 at 13:17 Comment(4)
Thanks, you just saved me a lot of time of not having to pass in the object to over 100+ templates.Cremator
In your template you also need to @import play.api.Play.current to make this work.Abmho
@Abmho I'm trying to do the same thing, and I'm getting a compiler warning that use of @import play.api.Play.current is deprecated. Do you know how this could be done with DI? I'm using Play 2.5 btwHowey
@RyanStull it's deprecated but you still need to do it that way. I think DI for templates will be supported from 2.6 onwards. Alternatively, you can use twirl 1.2 - see this thread for some details.Irrefrangible

© 2022 - 2024 — McMap. All rights reserved.