2012-05-14 25 views
4

給定一個foobar(每個包含一個名稱和一個用於創建URL超鏈接的slu))列表,Play 2.0中的慣用方式模板將此列表中的每個項目呈現爲一個鏈接(或其他HTML),然後用一些字符插入列表,如逗號?將列表映射到HTML並在Play 2.0模板中嵌入結果

例如,如果有三個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,這不是我想要的。

這似乎是一個常見的用例;有沒有可以實現的慣用方式?

回答

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,但。

+0

的HTML無意被打開到NodeSeq中,因爲那部分被解析爲文字輸出而不是Scala代碼。至少我認爲是。有時很難說。 – kes

+0

那麼代碼不起作用? – Debilski

+0

還沒有機會嘗試它。但+1是爲了引發NodeSeq(沒有想到這種可能性)。 – kes

2

您應該能夠使用HTML輔助停止逃跑......

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

這看起來應該起作用,但它會使文字「@ foobar.name」按字面呈現。奇怪的是,將@ foobar.name改爲{foobar.name}(不帶@)使它工作。必須是一個bug ... – kes

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> 
0

我能解決這個爲2.3播放,以及使用其他答案的組合:

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