Playframework 在运行时更改布局模板

Playframework 在运行时更改布局模板,playframework,playframework-2.1,Playframework,Playframework 2.1,在Kohana(PHP框架)中,布局是通过Template_Controller实现的,其中包含一个名为$Template的成员变量,该变量用作布局视图。 然后,在action方法中,您可以用更多的子视图(通常是content视图)填充$template。 () 这允许我在运行时更改布局“主题”。这对于多租户系统很有用,租户可以选择自己的主题(两列、三列等) 如何在PlayFramework2Scala中使用Scala模板引擎实现这一点? 换句话说,我希望有多个布局模板,租户可以从中进行选择。然

在Kohana(PHP框架)中,布局是通过Template_Controller实现的,其中包含一个名为$Template的成员变量,该变量用作布局视图。 然后,在action方法中,您可以用更多的子视图(通常是content视图)填充$template。 ()

这允许我在运行时更改布局“主题”。这对于多租户系统很有用,租户可以选择自己的主题(两列、三列等)

如何在PlayFramework2Scala中使用Scala模板引擎实现这一点? 换句话说,我希望有多个布局模板,租户可以从中进行选择。然后,控制器呈现布局模板和特定于操作的内容模板

类似(控制器的动作伪代码):

  • 根据用户检索布局主题(数据库中以字符串形式存储的名称,并具有相应的映射视图文件)
  • 呈现特定于操作的内容视图
  • 渲染从(1)和(2)中获得的布局视图
  • 注意:对于每个操作,布局主题可能会因用户而异,但内容视图保持不变

    在其文档中()
    内容模板,比如index.scala.html,包括对布局模板main.scala.html中定义的main的调用。换句话说,它是硬编码的,因此index.scala.html与main.scala.html紧密耦合

    我考虑使用反射从控制器调用main,然后传递内容

    另一种方法是使用解释模板引擎,如Scalate


    有什么建议吗?

    我认为有两种方法可以实现你的目标。第一种方法是将一个主题参数传递给模板(即,告诉被调用的模板要使用哪个主题/布局),并使用该参数有条件地调用布局模板。第二种方法是通过基于所选主题返回适当的视图来处理控制器内部的条件

    选项1

    在您的操作中,您需要向模板传递一些值,以指示要使用哪个主题

    def index = Action {
      Ok(views.html.index("two-col"))
    }
    
    然后在
    index.scala.html
    中执行以下操作:

    @(theme: String)
    
    @content = {
      <h1>Action Specific Content</h1>
    }
    
    @if("two-col" eq theme) {
      @twoCol("title")(content)
    } else {
      @main("title")(content)
    }
    
    注意:您也可以使用隐式参数传递主题,请参见此。这将减少在每次渲染时显式传递模板的需要

    选项2

    这将与控制器中的以下内容一样简单,但可能需要在视图模板中重复更多的代码

    def index = Action {
      var theme = ...
      ...
      if (theme eq 'tow-col') {
        Ok(views.html.twocol.index("two-col"))
      } else {
        Ok(views.html.default.index())
    }
    
    这假设在
    /app/views
    中有一个
    twocol
    default
    包,该包具有
    索引.scala.html

    其他评论

    从选项1可以看出,index.scala.html与main.scala.html没有紧密耦合。您可以将对main的调用替换为对任何其他模板的调用,甚至可以不调用任何模板

    FWIW,我会选择选项1,它可能会演变成更好的解决方案

    def index = Action {
      var theme = ...
      ...
      if (theme eq 'tow-col') {
        Ok(views.html.twocol.index("two-col"))
      } else {
        Ok(views.html.default.index())
    }