Java 添加<;脚本>;致<;头>;来自Play Framework 2中的scala模板标记

Java 添加<;脚本>;致<;头>;来自Play Framework 2中的scala模板标记,java,javascript,playframework,playframework-2.0,playframework-2.1,Java,Javascript,Playframework,Playframework 2.0,Playframework 2.1,我想从标签中向网页的添加javascript 这是我在页面上使用的等效脚本: main.scala.html @(title: String, scripts: Html = Html(""))(content: Html) <!DOCTYPE html> <html lang="nl"> <head> <title>@title</title> <meta http-equiv="cont

我想从标签中向网页的
添加javascript

这是我在页面上使用的等效脚本:

main.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}
mytag.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}
@(颜色:字符串)
$(文档).ready(函数(){
警惕(“@color”);
});
更多内容


在本例中,
标记是在HTML页面的一半呈现的,我想将
标记传递到
@scripts
变量中,这样它就可以在
标记中呈现。

这是可行的,但我同意ajozwik的说法,将脚本内联将更容易,并且仍然可以正常工作


您可以做的是将另一个参数组(基本上是另一个
(内容:Html)
)添加到主模板中,该模板将呈现使用
mytag
生成的
标记

main.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}
最后,你的页面看起来是这样的。请注意第二组花括号,这是在主模板上定义的
mytagScripts
。组之间的结束/开始大括号必须在同一行上,否则会出现编译器错误

page.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}

简化示例。。。如果您希望在一个页面中多次使用标记,那么您需要在
列表中跟踪
标记或其他内容。虽然概念相同,但因为您可以在
上下文中存储任何
对象
。args

为什么不将
mytag
传递到
main

page.scala.html

@import tags.html.mytag
@main("Title", mytag("green")) {
    <p>page content</p>
}
@import tags.html.mytag
@主(“标题”,mytag(“绿色”)){
页面内容

}
好的,我想出了一个更好的解决方案

我创建了以下标记:

script.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}
renderscripts.scala.html

@(title: String, scripts: Html = Html(""))(content: Html)
<!DOCTYPE html>
<html lang="nl">
    <head>
        <title>@title</title>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        @scripts
    </head>
    <body>
        @content
    </body>
</html>
@scripts = {
    <script type="text/javascript">
        $(document).ready(function() {
            alert(1);
        });
    </script>
}
@main("Title", scripts) {
    <p>page content</p>
}
@import tags._
@main("Title") {
    @mytag("green")
}
@(color: String)
<script type="text/javascript">
    $(document).ready(function() {
        alert('@color');
    });
</script>

<p>Some more content</p>
@(title: String, scripts: Html = Html(""))(content: Html)(implicit mytagScripts: Html = null)
<!DOCTYPE html>
<html lang="nl">
  <head>
    <title>@title</title>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    @scripts
    @mytagScripts
  </head>
  <body>
    @content
  </body>
</html>
@(color:String)
@{ctx().args.put("mytagScriptHtml", new Html("<script>alert('" + color + "');</script>"))}
<div>
  <!-- whatever else you're tag is generating -->
</div>
@import tags._
@main("Title") {
  @mytag("green")
} {
  @ctx().args.get("mytagScriptHtml")
}
@(content: Html)
@{
    var additionalScripts = ctx().args.get("additionalScripts").asInstanceOf[List[Html]];
    if(additionalScripts == null) {
        additionalScripts = new ArrayList[Html]();
        ctx().args.put("additionalScripts", additionalScripts)
    }

    val added = additionalScripts.add(content);
}
@additionalScripts = @{ctx().args.get("additionalScripts").asInstanceOf[List[Html]]}
@if(additionalScripts != null) {
    @for(additionalScript <- additionalScripts) {
        @additionalScript
    }
}
您可以使用以下命令在模板或标记中指定其他脚本:

@import tags._
@script {
    <script type="text/javascript">
        $(document).ready(function() {
            alert('This will be in the head!');
        });
    </script>
}
导入标记_ @剧本{ $(文档).ready(函数(){ 警惕(“这将在头部!”); }); }
这很好,对吗?:)


也许有人可以使用他们的Scala魔术清理或增强我的代码:)

我在Scala 2.4中做了类似的事情,但在正文结束标记之前,将脚本放入页脚。我不熟悉Play的JavaAPI,但我相信这个概念仍然有效

要点如下:

控制器/StackableAction.scala

// Borrowed from: https://github.com/rabitarochan/Play2-ChainAction/blob/master/core/src/main/scala/com/github/rabitarochan/play2/stackableaction/StackableAction.scala
abstract class StackableAction extends ActionBuilder[RequestWithAttributes] with StackableFilter {

  override def filter[A](request: RequestWithAttributes[A])(f: RequestWithAttributes[A] => Future[Result]): Future[Result] = {
    f(request)
  }

  def invokeBlock[A](req: Request[A], block: RequestWithAttributes[A] => Future[Result]): Future[Result] = {
    val reqWA = new RequestWithAttributes(req, new TrieMap[AttributeKey[_], Any]())
    filter(reqWA)(block)
  }

}

trait StackableFilter {
  def filter[A](request: RequestWithAttributes[A])(f: RequestWithAttributes[A] => Future[Result]): Future[Result]
}

trait AttributeKey[A] {
  def ->(value: A): Attribute[A] = Attribute(this, value)
}

case class Attribute[A](key: AttributeKey[A], value: A) {
  def toTuple: (AttributeKey[A], A) = (key, value)
}

class RequestWithAttributes[A](request: Request[A], attributes: TrieMap[AttributeKey[_], Any]) extends WrappedRequest[A](request) {
  def get[B](key: AttributeKey[B]): Option[B] = attributes.get(key).asInstanceOf[Option[B]]
  def set[B](key: AttributeKey[B], value: B): RequestWithAttributes[A] = {
    attributes.put(key, value)
    this
  }
  def getAll[T](implicit classTag: ClassTag[T]) = {
    attributes.filterKeys {
      case p: T => true
      case _    => false
    }
  }
}
views/support/JavascriptPage.scala

object JavascriptPage {
  case class NonBlockingJS(key: String) extends AttributeKey[Html]
  case class BlockingJS(key: String) extends AttributeKey[Html]

  def addNonBlockingJS(div: String)(jscript: Html)(implicit request: Request[_]): Unit = {
    request match {
      case i: RequestWithAttributes[_] =>
        i.set(NonBlockingJS(div), jscript)
      case _ =>
    }
  }

  // scripts that are supposed to go into the <head> tag, thus blocking scripts
  def addBlockingJS(div: String)(jscript: Html)(implicit request: Request[_]): Unit = {
    request match {
      case i: RequestWithAttributes[_] =>
        i.set(BlockingJS(div), jscript)
      case _ =>
    }
  }

  // scripts that are supposed to go before the </body> tag, non blocking scripts that is
  def getNonBlockingJS()(implicit request: Request[_]): Seq[(String, Html)] = {
    request match {
      case i: RequestWithAttributes[_] =>
        i.getAll[NonBlockingJS].toSeq.map {
          case (NonBlockingJS(div), jscript: Html) => (div, jscript)
        }
      case _ => Seq.empty
    }
  }
}
对象JavascriptPage{
case类NonBlockingJS(key:String)扩展了AttributeKey[Html]
case类BlockingJS(key:String)扩展了AttributeKey[Html]
def addNonBlockingJS(div:String)(jscript:Html)(隐式请求:请求[]):单位={
请求匹配{
案例一:RequestWithAttributes[\u]=>
i、 集合(非阻塞JS(div),jscript)
案例=>
}
}
//应该进入标记的脚本,从而阻止脚本
def addBlockingJS(div:String)(jscript:Html)(隐式请求:请求[]):单位={
请求匹配{
案例一:RequestWithAttributes[\u]=>
i、 set(BlockingJS(div),jscript)
案例=>
}
}
//应该放在标记前面的脚本,非阻塞脚本
def getNonBlockingJS()(隐式请求:请求[]):Seq[(字符串,Html)]={
请求匹配{
案例一:RequestWithAttributes[\u]=>
i、 getAll[NonBlockingJS].toSeq.map{
大小写(NonBlockingJS(div),jscript:Html)=>(div,jscript)
}
大小写=>序号为空
}
}
}
InlineOnBlockingjs.scala.html

@import views.support.JavascriptPage
@(implicit request: Request[_])
<script src="/javascripts/your_javascript_app.js"></script>
<script id="non-blocking" type="text/javascript">
  @defining(JavascriptPage.getNonBlockingJS()) { scripts =>
    @scripts.map { case (_, item) => @item }
  }
</script>
@import views.support.JavascriptPage
@(隐式请求:请求[3;])
@正在定义(JavascriptPage.getNonBlockingJS()){scripts=>
@scripts.map{case({,item)=>@item}
}

它基本上用一个case类包装请求(使用play的action composition),这个case类的一个成员是TrieMap,然后它将作为与请求相关联的额外属性的持有者,这些属性可以是javascript条目,也可以是您在请求生命周期内想要拥有和共享的任何东西。

如果您只是添加javascript内联,它应该仍然可以工作。太棒了!这很有效。我必须说我还不完全明白发生了什么。关于隐式参数的文档不是很详细。@Thijs您可以在这里“布局”下查看参数组内容的文档。老实说,我也不完全理解“隐式”关键字。我只知道,当我没有把它放在那里时,我在试图设置默认值时遇到了一个编译器错误:因为mytag必须在页面内容之外呈现一些额外的HTML。请稍候。。。如果您有一个只用于脚本的标记,那么只做您最初使用的不是更容易吗?正如你所说的“moreScript等价物”。