播放视图中的变量

variables in play views

我在网上找到了一些关于我的问题的答案,但都是针对不再有效的旧版游戏。

我正在尝试找到一种方法来使用变量作为模板路径的一部分。 我知道这将删除类型检查等,但它是一个 generator/prototyping/internal 工具,不会看到 public/outside 世界。

代码如下:

我能找到的最佳解决方案是:

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));
}

我正在使用带有 scala 的最新播放框架 (2.5.*)。

使用火柴是唯一的方法吗? 一定要有动态为什么要return一个视图?

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]] 这就是我卡住的地方

我在这里添加了一个答案,只是为了帮助遇到此问题的其他人。

@Mikesname 是正确的,删除​​ Some() 并且它 'should' 一切正常。

问题是我动态加载了 class/view 名称,但我没有使用完整的 class 名称。当我应该加载 view.html.something.

时,我正在加载 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 更好的方法来处理索引视图部分,但是对于我正在构建的工具来说这很好