将列表映射到HTML并将结果插入Play 2.0模板中

时间:2012-05-14 03:42:58

标签: templates scala playframework playframework-2.0

给定一个foobars列表(每个都包含一个名称,以及一个用于创建URL超链接的slug),Play 2.0模板中的惯用方法是将此列表中的每个项目呈现给链接(或者其他一些HTML),然后将列表插入一些字符,如逗号?

例如,如果有三个foobars,最终输出可能如下所示:

<a href="/quux/foobar1">Foobar1</a>, <a href="/quux/foobar2">Foobar2</a>, <a href="/quux/foobar3">Foobar3</a>

我的第一个冲动是尝试:

@foobars.map{foobar => 
<a href="@routes.Foobars.quux(foobar.slug)">@foobar.name</a>
}.mkString(", ")

但是这会输出转义的HTML,这不是我想要的。

这似乎是一个常见的用例;是否有一种惯用的方式可以实现?

4 个答案:

答案 0 :(得分:2)

您应该可以使用Html帮助程序来停止转义...

@{Html(foobars.map{foobar => 
    <a href="@routes.Foobars.quux(foobar.slug)">@foobar.name</a>
}.mkString(", "))}

答案 1 :(得分:1)

我没有使用Play,但我认为mkString似乎是问题所在。它将您精心构建的NodeSeq转换为String,然后将其传递给Play的HTML输出例程,并将其转换为Text(包括转义)。

为避免这种情况:

@foobars.map{foobar => 
  <a href="@routes.Foobars.quux(foobar.slug)">@foobar.name</a>
}.reduceLeft((e1: xml.NodeSeq, e2: xml.NodeSeq) => e1 ++ xml.Text(", ") ++ e2)

(对于一个空的foobar序列,这将失败。你必须先查看reduceLeftOption。)

但Play API中可能有一个专门的功能。

答案 2 :(得分:1)

根据Debilski的想法,我建立了一个工作版本。但遗憾的是,在追加时我得到了额外的空间。没什么大不了的,但它就在那里:

<td>
    @r.countries.map{ country =>
      <a href="@routes.Items.editCountry(country.toString, "main")">
         @Country.findOneByID(country).map(_.name)
      </a>
    }.reduceLeftOption((e1: Html, e2: Html) => e1 += Html(",") += e2)
</td>

答案 3 :(得分:0)

我也可以使用其他答案的组合来解决Play 2.3的问题:

@foobars.map{foobar =>
    <a href="@routes.Foobar.quux(foobar.slug)">@foobar.name</a>
}.reduceLeftOption((e1: Html, e2: Html) => Html(e1 + "," + e2))