🐷
Goのtemplateで改行を`<br>`にする
やってみました
背景
Goのテンプレートを使い、HTMLのテンプレートに文字列を埋め込んだりする場合、元の文字列が改行を含んでいるような場合はよくあると思います。
そのようなとき、そのままテンプレートに渡してしまうとHTMLは\n
のような改行コードを改行と認識しませんので、どうにかして改行タグである<br>
に変換してあげる必要があります。
実装
package main
import (
"log"
"os"
"strings"
"text/template"
)
const tpl = `<!DOCTYPE html>
<html>
<head></head>
<body>
<p>{{applyBrNewline (htmlEscape .)}}</p>
</body>
</html>
`
const text = `1 < 100
は
「1 小なり 100」と
読みます。`
func main() {
funcMap := template.FuncMap{
"htmlEscape": func(in string) string {
out := template.HTMLEscapeString(in)
return out
},
"applyBrNewline": func(in string) string {
out := strings.Replace(in, "\n", "<br>", -1)
return out
},
}
t, err := template.New("").Funcs(funcMap).Parse(tpl)
if err != nil {
log.Fatal(err)
}
if err := t.Execute(os.Stdout, text); err != nil {
log.Fatal(err)
}
}
結果
<!DOCTYPE html>
<html>
<head></head>
<body>
<p>1 < 100<br>は<br>「1 小なり 100」と<br>読みます。</p>
</body>
</html>
元の文字列に含まれていた改行が<br>
になり、ついでに<
が<
に変換されているのがわかると思います。
入力となる文字列を埋め込む前に、strings.Replace
やtemplate.HTMLEscapeString
を使ってよしなに加工してあげるのがキモとなります。
それぞれの処理はtemplate.FuncMap
を使って呼び出すようにし、再利用性を少し高めてみました。
funcを入れ子にする場合には内側の結果をfuncごと()
でくくってあげれば、内側のfuncの結果がそのまま外側のfuncに順次渡されるようです。
ではまた!
Discussion