Scala 如何在play framework 2中使用脚本处理多层模板?
我有这样一个模板结构:Scala 如何在play framework 2中使用脚本处理多层模板?,scala,playframework-2.0,template-engine,Scala,Playframework 2.0,Template Engine,我有这样一个模板结构: modal.scala.view @() ... HTML code to display a modal in my app ... /** * Output type for components to render body, head and end-of-body content * @param bodyMarkup the visual part of the component output * @param resources tags f
modal.scala.view
@()
... HTML code to display a modal in my app ...
/**
* Output type for components to render body, head and end-of-body content
* @param bodyMarkup the visual part of the component output
* @param resources tags for content to include in the head or footer
*/
case class MultipartHtml(bodyMarkup: Html, resources: Seq[MultipartHtml.Resource] = Nil) {
import com.huffpost.hyperion.lib.MultipartHtml._
/**
* Apply a transformation to the body content of this object
* @param bodyMapper transformation function
* @return a new object with transformed body content
*/
def map(bodyMapper: Html => Html): MultipartHtml = MultipartHtml(bodyMapper(bodyMarkup), resources)
/**
* @param bodyMapper transformation function
* @return the bodyMapper result combined with the component resource list
*/
def flatMap(bodyMapper: Html => MultipartHtml): MultipartHtml = bodyMapper(bodyMarkup) ++ resources
/**
* Add a head and/or footer content to this object
* @param resources the resources to add
* @return a new object with the resource added
*/
def ++(resources: GenTraversableOnce[Resource]): MultipartHtml = resources.foldLeft(this)(_ :+ _)
/**
* Add a head or footer content to this object
* @param resource the resource to add
* @return a new object with the resource added
*/
def :+(resource: Resource): MultipartHtml = MultipartHtml(bodyMarkup, (resources :+ resource).distinct)
/**
* Prepend a head or footer content to this object
* @param resource the resource to add
* @return a new object with the resource added
*/
def +:(resource: Resource): MultipartHtml = MultipartHtml(bodyMarkup, (resource +: resources).distinct)
/** Get tags by resource type for injection into a template */
def renderResourcesByType(resourceType: ResourceType): Html = Html(resources.filter(_.resourceType == resourceType).mkString("\n"))
}
/** Utility methods for MultipartHtml type */
object MultipartHtml {
/** Empty MultipartHtml */
def empty = MultipartHtml(Html(""))
/** A resource that can be imported in the HTML head or footer*/
trait ResourceType
trait Resource {
def resourceType: ResourceType
}
object HeadTag extends ResourceType
object FooterTag extends ResourceType
/** A style tag */
case class StyleTag(styleUrl: String) extends Resource {
val resourceType = HeadTag
override def toString = {
val assetUrl = routes.Assets.at(styleUrl).url
s"""<link rel="stylesheet" type="text/css" media="screen" href="$assetUrl">"""
}
}
/** A script tag */
case class ScriptTag(scriptUrl: String) extends Resource {
val resourceType = FooterTag
override def toString = {
val assetUrl = routes.Assets.at(s"javascript/$scriptUrl").url
s"""<script type="text/javascript" src="$assetUrl"></script>"""
}
}
}
我想在modal.scala.view中保留modal的脚本,但我找不到将脚本从子模板传递到父模板的方法,以便在主模板的正确位置渲染它们。有什么想法吗?提前谢谢 我认为对你的问题没有一个游戏团队认可的标准答案,但我可以想到两种方法:一元方法和命令式方法 在子控制器中包裹视图;在输出中封装脚本 我正在从事的一个大型项目使用这种策略。我们创建了一个
MultipartHtml
类型,其中包含应该包含在文档正文中的Html
输出,以及一个我们创建的名为Resources
的类型,其中包含应该放在别处的内容。我们将这种类型视为monad,这样我们就可以map
和flatMap
它来操作Html
文档内容,同时积累和消除资源的重复
我们所有的控制器都返回多端口tml
。它们从视图的结果构造一个实例,然后简单地将:+
资源
标记到结果。我们的页面级控制器将这些部分组合在一起。我们所做工作的核心如下:
modal.scala.view
@()
... HTML code to display a modal in my app ...
/**
* Output type for components to render body, head and end-of-body content
* @param bodyMarkup the visual part of the component output
* @param resources tags for content to include in the head or footer
*/
case class MultipartHtml(bodyMarkup: Html, resources: Seq[MultipartHtml.Resource] = Nil) {
import com.huffpost.hyperion.lib.MultipartHtml._
/**
* Apply a transformation to the body content of this object
* @param bodyMapper transformation function
* @return a new object with transformed body content
*/
def map(bodyMapper: Html => Html): MultipartHtml = MultipartHtml(bodyMapper(bodyMarkup), resources)
/**
* @param bodyMapper transformation function
* @return the bodyMapper result combined with the component resource list
*/
def flatMap(bodyMapper: Html => MultipartHtml): MultipartHtml = bodyMapper(bodyMarkup) ++ resources
/**
* Add a head and/or footer content to this object
* @param resources the resources to add
* @return a new object with the resource added
*/
def ++(resources: GenTraversableOnce[Resource]): MultipartHtml = resources.foldLeft(this)(_ :+ _)
/**
* Add a head or footer content to this object
* @param resource the resource to add
* @return a new object with the resource added
*/
def :+(resource: Resource): MultipartHtml = MultipartHtml(bodyMarkup, (resources :+ resource).distinct)
/**
* Prepend a head or footer content to this object
* @param resource the resource to add
* @return a new object with the resource added
*/
def +:(resource: Resource): MultipartHtml = MultipartHtml(bodyMarkup, (resource +: resources).distinct)
/** Get tags by resource type for injection into a template */
def renderResourcesByType(resourceType: ResourceType): Html = Html(resources.filter(_.resourceType == resourceType).mkString("\n"))
}
/** Utility methods for MultipartHtml type */
object MultipartHtml {
/** Empty MultipartHtml */
def empty = MultipartHtml(Html(""))
/** A resource that can be imported in the HTML head or footer*/
trait ResourceType
trait Resource {
def resourceType: ResourceType
}
object HeadTag extends ResourceType
object FooterTag extends ResourceType
/** A style tag */
case class StyleTag(styleUrl: String) extends Resource {
val resourceType = HeadTag
override def toString = {
val assetUrl = routes.Assets.at(styleUrl).url
s"""<link rel="stylesheet" type="text/css" media="screen" href="$assetUrl">"""
}
}
/** A script tag */
case class ScriptTag(scriptUrl: String) extends Resource {
val resourceType = FooterTag
override def toString = {
val assetUrl = routes.Assets.at(s"javascript/$scriptUrl").url
s"""<script type="text/javascript" src="$assetUrl"></script>"""
}
}
}
然后在模板中,您可以执行以下操作:
@(addTag: Html => Unit)
@addTag {
<script src="myscript.js"></script>
}
@* Generate HTML *@
@(addTag:Html=>单位)
@地址标签{
}
@*生成HTML*@
这里的缺点是,您必须以某种方式将此对象向下转发,如果您的局部视图层次结构深入,这可能会很痛苦 谢谢你,阿杰。我将尝试命令式方法,因为我在java play中工作。如果成功,我将在这里报告结果。再次感谢!可变的方式很好地工作。使用隐式,我可以避免将所有模板与可变对象混在一起。谢谢你,伙计。
@(addTag: Html => Unit)
@addTag {
<script src="myscript.js"></script>
}
@* Generate HTML *@