Skip to content Skip to sidebar Skip to footer

Html/templates - Replacing Newlines With

I'm loading a text file that has newlines in it, and pass it to html/templates. Substituting the \n with in the loaded string, they are escaped by the template to html &

Solution 1:

It seems you could run template.HTMLEscape() on your text first to sanitize it, then do the \n to substitution that you trust, then use that as pre-escaped and trusted template data.

Update: Expanding on Kocka's example, this is what I had in mind:

package main

import (
    "html/template"
    "os"
    "strings"
)

const page = `<!DOCTYPE html><html><head></head><body><p>{{.}}</p></body></html>`

const text = `first line
<script>dangerous</script>
last line`

func main() {
    t := template.Must(template.New("page").Parse(page))
    safe := template.HTMLEscapeString(text)
    safe = strings.Replace(safe, "\n", "<br>", -1)
    t.Execute(os.Stdout, template.HTML(safe)) // template.HTML encapsulates a known safe HTML document fragment.
}

http://play.golang.org/p/JiH0uD5Zh2

Output is

<!DOCTYPE html><html><head></head><body><p>first line<br>&lt;script&gt;dangerous&lt;/script&gt;<br>last line</p></body></html>

And text rendered in the browser is

first line
<script>dangerous</script>
last line

Solution 2:

Not sure where you're substituting \n for <br> but if it's in go, you can cast the string as template.HTML so it's not escaped.

See: http://golang.org/pkg/html/template/#HTML

If it's in a template, there should be a pipeline available, {{. | html}}

Solution 3:

You can do it like this:

package main

import (
    "html/template"
    "os"
)

const page = `<!DOCTYPE html><html><head></head><body><p>{{.}}</p></body></html>`

func main() {
    t := template.Must(template.New("page").Parse(page))
    t.Execute(os.Stdout, template.HTML("<br>"))
}

Try it out!

Solution 4:

The accepted answer can easily be turned into a custom template function:

funcreplaceNewline(s string) template.HTML {
    return template.HTML(strings.Replace(template.HTMLEscapeString(s), "\n", "<br>", -1))
}

Add it with func (*Template) Funcs

Example

package main

import (
    "html/template""os""strings"
)

const page = `<!DOCTYPE html>
<html>
  <body>
    <p>{{. | replaceNewline}}</p>
  </body>
</html>`const text = `first line
<script>dangerous</script>
last line`funcmain() {
    t := template.Must(template.New("page").Funcs(template.FuncMap{
        "replaceNewline": func(s string) template.HTML {
            return template.HTML(strings.Replace(template.HTMLEscapeString(s), "\n", "<br>", -1))
        },
    }).Parse(page))
    t.Execute(os.Stdout, text)
}

Output

<!DOCTYPE html><html><body><p>first line<br>&lt;script&gt;dangerous&lt;/script&gt;<br>last line</p></body></html>

Go Playground

Solution 5:

It is unnecessary to pass your entire template as an unsafe template (and this is bad practice).

You should pass a map to your template, and only explicitly 'unsafe' the elements you want to use as such, eg.

package main

import"bytes"import"fmt"import"html/template"import"strings"var input = `
  {{ define "LAYOUT" }}
    <html>
      <body>
        {{ template "CONTENT" . }}
      </body>
    </html>
  {{ end }}

  {{ define "CONTENT" }}
    Unsafe content: {{ .Unsafe }}
    Newlines converted to <br/> follow:
    {{ .Normal }}
  {{ end }}

  {{ template "LAYOUT" . }}
`var other = `
  Hello
  World
  Again
`var other2 = `
  <script>alert("Owned!");</script>
`funcmain() {

    var t, err = template.New("sample").Parse(input)
    if err != nil {
        panic(err)
    }

    var fixed = strings.Replace(other, "\n", "\n<br/>", -1)
    var model = map[string]interface{}{
        "Normal": template.HTML(fixed),
        "Unsafe": other2,
    }

    var out bytes.Buffer
    t.Execute(&out, model) # <--- !! Notice the model is NOT an HTML type.

    var raw = out.String()
    fmt.Printf("%s", raw)
}

Yields:

Unsafe content:    &lt;script&gt;alert(&#34;Owned!&#34;);&lt;/script&gt;

Newlines converted to <br/> follow:
 <br/>  Hello 
 <br/>  World 
 <br/>  Again 
 <br/></body></html>

Post a Comment for "Html/templates - Replacing Newlines With
"