【问题标题】:Changing layout template in runtime在运行时更改布局模板
【发布时间】:2013-06-24 12:54:04
【问题描述】:

在 Kohana(PHP 框架)中,布局是通过 Template_Controller 实现的,它包含一个名为 $template 的成员变量,用作布局视图。 然后在 action 方法中,您可以使用更多的子视图填充 $template,通常是内容视图。 (http://forum.kohanaframework.org/discussion/3612/kohana-layout-system/p1)

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

如何使用 Scala 模板引擎在 playframework 2 Scala 中实现这一点? 换句话说,我想要多个布局模板供租户选择。然后控制器呈现布局模板和特定于操作的内容模板。

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

  1. 根据用户,检索布局主题(以字符串形式存储在数据库中的名称,并具有相应的映射视图文件)。
  2. 呈现特定于操作的内容视图。
  3. 将从 (1) 获得的布局视图与 (2) 一起渲染。

注意:对于每个操作,布局主题可能会因用户而异,但内容视图保持不变。

在它的文档中 (http://www.playframework.com/documentation/2.1.1/ScalaTemplateUseCases)
内容模板,例如 index.scala.html,包括对 main.scala.html 布局模板中定义的 main 的调用。换句话说,它是硬编码的,因此 index.scala.html 与 main.scala.html 紧密耦合。

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

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

有什么建议吗?

【问题讨论】:

    标签: playframework playframework-2.1


    【解决方案1】:

    我看到了 2 个选项来完成您所追求的目标。第一个是将主题参数传递给您的模板(即告诉被调用模板使用哪个主题/布局)并使用该参数有条件地调用布局模板。第二种是通过根据所选主题返回适当的视图来处理控制器内部的条件。

    选项 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)
    }
    

    这会期望有一个twoCol.scala.html 模板,例如:

    @(title: String)(content: Html)
    <!DOCTYPE html>
    <html>
      ...
      <body>
        <h1>Two Column</h1>
        @content
      </body>
    </html>
    

    注意:您也可以使用隐式参数传递主题,请参阅SO question。这将减轻在每次渲染时显式传递模板的需要。

    选项 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 中有一个twocoldefault 包,它们有一个index.scala.html

    附加评论

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

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

    【讨论】:

      猜你喜欢
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      • 2013-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多