🐷

Goのtemplateで改行を`<br>`にする

2022/10/20に公開約1,500字

やってみました

https://go.dev/play/p/xudRUuFD8of

背景

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 &lt; 100<br>は<br>「1 小なり 100」と<br>読みます。</p>
  </body>
</html>

元の文字列に含まれていた改行が<br>になり、ついでに<&lt;に変換されているのがわかると思います。

入力となる文字列を埋め込む前に、strings.Replacetemplate.HTMLEscapeStringを使ってよしなに加工してあげるのがキモとなります。
それぞれの処理はtemplate.FuncMapを使って呼び出すようにし、再利用性を少し高めてみました。

funcを入れ子にする場合には内側の結果をfuncごと()でくくってあげれば、内側のfuncの結果がそのまま外側のfuncに順次渡されるようです。

ではまた!

参考

https://ja.stackoverflow.com/questions/38639/golangのテンプレートで改行が反映されない

Discussion

ログインするとコメントできます