我已经在网上找到了一些我的问题的答案,但所有旧版本的游戏都不再适用。
我试图找到一种方法来将变量用作模板路径的一部分。 我知道这将删除类型检查等,但它用于生成器/原型/内部工具,并且不会看到公共/外部世界。
这里是codez:
我能找到的最佳答案是:
def index(page: String) = Action {
page match {
case "something" => Ok(views.html.examples.something())
case "else" => Ok(views.html.examples.else())
case "another" => Ok(views.html.examples.elements.another())
}
}
理想情况下这样的事情会更有意义:
def index(page: String) = Action {
Ok(views.html.getClassFromStringOrSomething(page));
}
我正在使用最新的Play框架(2.5。*)和scala。
唯一的方式是使用匹配? 必须有一个动态的回归视图?
n.b。我发现大量在线使用play.api.templates.Html/play.twirl.api.Html
似乎不再有效的建议,Html
无法找到,所以我猜猜api的版本有其他变化。
使用我得到:
def index(page: String, parent: String) = Action {
val clazz: Class[_] = Play.current.classloader.loadClass(page)
val render: Method = clazz.getDeclaredMethod("render")
val view = Some(render.invoke(clazz).asInstanceOf[play.twirl.api.Html])
Ok(view)
}
这给我错误
Cannot write an instance of Some[play.twirl.api.Html] to HTTP response. Try to define a Writeable[Some[play.twirl.api.Html]]
这就是我被困的地方
答案 0 :(得分:0)
我在这里添加了一个答案,仅仅是为了帮助其他人解决这个问题。
@Mikesname是正确的,删除Some()
并且'应该'一切正常。
问题是我正在动态加载类/视图名称,但我没有使用完整的类名。我应该在加载something
时加载view.html.something
。
这是我用来使该功能正常工作的代码
(需要清理但是它正常工作,还会在目录中记录名为index
的视图,即views.html.parent -> /parent/index.scala.html
package controllers
import javax.inject.{Inject, Singleton}
import play.api.Play
import play.api.mvc.{Action, Controller}
import play.twirl.api.Html
@Singleton
class PathController @Inject() extends Controller {
def index(page: String, parent: String, grandparent: String) = Action {
Ok(buildView(buildClassName(page, parent, grandparent)))
}
def buildClassName(page: String, parent: String, grandparent: String): String = {
val pathGrandParent = if (grandparent != null) grandparent + '.' else ""
val pathParent = if (parent != null) parent + '.' else ""
"views.html." + pathGrandParent + pathParent + page
}
def loadClass(name: String): Class[_] = {
try {
Play.current.classloader.loadClass(name)
} catch {
case _: Throwable => {
Play.current.classloader.loadClass(name + ".index")
}
}
}
def buildView(name: String): Html = {
val clazz = loadClass(name)
clazz.getDeclaredMethod("render").invoke(clazz).asInstanceOf[play.twirl.api.Html]
}
}
我认为有一个更好的方法来做一个try / catch的索引视图部分,但它对我正在构建的工具很好