4

给定一个 foobar 列表(每个都包含一个名称和一个用于创建 URL 超链接的 slug),在 Play 2.0 模板中将该列表中的每个项目呈现为链接(或其他一些 HTML)的惯用方式是什么? ),然后在列表中插入一些字符,比如逗号?

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

<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

4 回答 4

2

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

@{Html(foobars.map{foobar => 
    <a href="@routes.Foobars.quux(foobar.slug)">@foobar.name</a>
}.mkString(", "))}
于 2012-07-31T14:36:15.297 回答
1

我没有用过Play,但我认为这mkString似乎是问题所在。它将您精心构建的 a 转换NodeSeq为 a String,然后将其传递给 Play 的 HTML 输出例程,在那里它被转换为 a 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 中可能有专门的函数。

于 2012-05-14T08:56:14.363 回答
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>
于 2014-03-19T21:03:06.423 回答
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))
于 2014-11-06T15:10:23.317 回答