38661


Golangのテンプレートを利用して、HTMLを出力しているのですが。

[code]

    あああ
    いいい
    ううう
    
[/code]

このような内容の文章を出力すると

[code]

    あああ いいい ううう
    
[/code]

と表示されてしまいます。

<https://stackoverflow.com/questions/12671713/golang-how-to-replace-n-with-
br/12672021>

上の方法を試しましたが

[code]

    あああ <br>
    いいい <br>
    ううう <br>
    
[/code]

となって`<br>`が表示されてしまいます。

<http://m-shige1979.hatenablog.com/entry/2016/01/29/080000>

こちらのサイトで紹介されている`safe`関数を用いた方法では`<br>`が評価され、改行されましたが、当然XSSの脆弱性があります。  
どのようにすれば改行をHTMLに反映させることができるのでしょうか。


CC BY-SA 3.0
2017-10-12T09:49:33.483
38639
2017-10-13T02:55:12.087
7232
question
html go
Golangのテンプレートで改行が反映されない。


サンプルとして、次のテキストを `p` タグの中に入れることを考えます。

[code]

    const text = `あいう
    かきく
    さしす
    `
    
[/code]

## 方法1

エスケープした後、改行を `<br>` に変換するようにすれば良いです。 [(Go
Playground)](https://play.golang.org/p/VAJJoNhHth)

[code]

    const tpl = `<!DOCTYPE html>
    <html>
      <head></head>
      <body>
        <p>{{.}}</p>
      </body>
    </html>
    `
    
    func main() {
        t := template.Must(template.New("sample").Parse(tpl))
        safeText := template.HTMLEscapeString(text)
        replacedText := strings.Replace(safeText, "\n", "<br>", -1)
        if err := t.Execute(os.Stdout, template.HTML(replacedText)); err != nil {
            log.Fatal(err)
        }
    }
    
[/code]

## 方法2

あるいは1行ごとにスライスとして持っておけば [`range`
アクション](https://golang.org/pkg/text/template/#hdr-
Actions)が使えるので、テキストではなくテンプレートの方に `<br>` を入れることができます。 [(Go
Playground)](https://play.golang.org/p/JOEu1SD_6i)

[code]

    const tpl = `<!DOCTYPE html>
    <html>
      <head></head>
      <body>
        <p>{{range .HeadLines}}{{ . }}<br>{{end}}{{if .LastLine}}{{ .LastLine }}{{end}}</p>
      </body>
    </html>
    `
    
    func main() {
        // 末尾が改行されているかどうかで処理を分けなければいけない
        allLines := strings.Split(text, "\n")
        data := struct {
            HeadLines []string
            LastLine  string
        }{
            HeadLines: allLines[:len(allLines)-1],
            LastLine:  allLines[len(allLines)-1],
        }
    
        t, err := template.New("sample").Parse(tpl)
        if err != nil {
            log.Fatal(err)
        }
    
        if err := t.Execute(os.Stdout, data); err != nil {
            log.Fatal(err)
        }
    }
    
[/code]


CC BY-SA 3.0
2017-10-13T02:55:12.087
38661
2017-10-13T02:55:12.087
19110
38639
answer