2013-06-24 76 views
6

在Kohana(PHP框架)中,布局是通过Template_Controller实现的,该模板继承了名为$ 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定义的主要的呼叫时,布局模板。换句话说,它是硬编码的,因此index.scala.html与main.scala.html紧密耦合。

我虽然关于使用反射调用主控制器,然后传递内容。

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

有什么建议吗?

回答

2

我看到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()) 
} 

这假定有一个twocoldefault包在/app/views具有一个index.scala.html

附加评论

你可以从选项1讲,i​​ndex.scala.html不紧密结合main.scala.html。您可以将呼叫替换为任何其他模板的呼叫,甚至不需要模板。

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