英文:
Newline to <br/>
问题
我正在尝试在我的Golang模板中将"\n
"转换为"<br/>
"。
type Page struct {
HTTPMethod string
Template string
CharSet string
Slug string
MetaTitle string
MetaDescription string
MetaKeywords string
Title string
Body string
Navigation Links
Detail interface{}
}
for _, page := range pages.Pages {
page := page
router.HandleFunc(page.Slug, func(w http.ResponseWriter, r *http.Request) {
err := tmpl.ExecuteTemplate(w, page.Template, page)// page of type Page
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
}
模板如下:
{{define "index"}}{{template "header" . }}<h1>{{.Title}}</h1><div>{{.Body}}</div>{{template "footer"}}{{end}}
我尝试使用以下代码连接字符串:
page.Body = "Some text." +htmlBRTag+ "More text"
输出如下:
htmlBRTag := "<br/>" // -> <br/>
htmlBRTag = "<br/>" //-> <br/>
预期结果应该是:
page.Body = "Some text.<br/>More text"
有什么建议吗?
以下是可以直接运行的可复制代码:
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
type Data struct {
Field1 string
Field2 string
Field3 string
}
var tmpl *template.Template
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Recovering from panic, error is: %v \n", r)
}
}()
router := mux.NewRouter()
port := ":8085"
htmlBreak := "<br/>"
data := Data{}
data.Field1 = "Some text<br/>More text"
data.Field2 = "Some text" + htmlBreak + "More text"
data.Field3 = template.HTMLEscapeString(data.Field2)
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
err := tmpl.ExecuteTemplate(w, "index", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
var err error
tmpl, err = template.ParseGlob("views/*")
if err != nil {
panic(err.Error())
}
router.PathPrefix("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
http.FileServer(http.Dir("./static/")).ServeHTTP(res, req)
})
fmt.Println("Server running on localhost" + port)
err = http.ListenAndServe(port, handlers.CompressHandler(router))
if err != nil {
log.Fatal(err)
}
}
在./views文件夹中有index.html、index.html和footer.html:
{{define "header"}}<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>{{end}}
{{define "index"}}{{template "header" . }}
<div>F1: {{.Field1}}</div>
<div>F2: {{.Field2}}</div>
<div>F3: {{.Field3}}</div>
{{template "footer"}}{{end}}
{{define "footer"}}</body></html>{{end}}
当前输出为:
F1: Some text<br/>More text
F2: Some text<br/>More text
F3: Some text&lt;br/&gt;More text
预期结果是换行符:
Some text
More text
我尝试了以下代码:
htmlBRTag := "<br/>"
b = "Some text." +htmlBRTag+ "More text"
Page.Body = template.HTMLEscapeString(b)
模板中的文本变为:
Some text.&lt;br/&gt;More text
英文:
I am attempting to convert my "\n
" to "<br/>
" in my Golang templates.
type Page struct {
HTTPMethod string
Template string
CharSet string
Slug string
MetaTitle string
MetaDescription string
MetaKeywords string
Title string
Body string
Navigation Links
Detail interface{}
}
for _, page := range pages.Pages {
page := page
router.HandleFunc(page.Slug, func(w http.ResponseWriter, r *http.Request) {
err := tmpl.ExecuteTemplate(w, page.Template, page)// page of type Page
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
}
The template looks like:
{{define "index"}}{{template "header" . }}<h1>{{.Title}}</h1><div>{{.Body}}</div>{{template "footer"}}{{end}}
I attempted to concatenate the string with:
page.Body = "Some text." +htmlBRTag+ "More text"
Which outputs the following:
htmlBRTag := "&lt;br/&gt;" // -> &lt;br/&gt;
htmlBRTag = "<br/>" //-> <br/>
The expected outcome would be:
page.Body = "Some text.<br/>More text"
Any suggestions how to do this?
Below is replicable code that runs out of the box:
package main
import (
"fmt"
"html/template"
"log"
"net/http"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
type Data struct {
Field1 string
Field2 string
Field3 string
}
var tmpl *template.Template
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Printf("Recovering from panic, error is: %v \n", r)
}
}()
router := mux.NewRouter()
port := ":8085"
htmlBreak := "<br/>"
data := Data{}
data.Field1 = "Some text<br/>More text"
data.Field2 = "Some text" + htmlBreak + "More text"
data.Field3 = template.HTMLEscapeString(data.Field2)
router.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
err := tmpl.ExecuteTemplate(w, "index", data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
})
var err error
tmpl, err = template.ParseGlob("views/*")
if err != nil {
panic(err.Error())
}
router.PathPrefix("/").HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
http.FileServer(http.Dir("./static/")).ServeHTTP(res, req)
})
fmt.Println("Server running on localhost" + port)
err = http.ListenAndServe(port, handlers.CompressHandler(router))
if err != nil {
log.Fatal(err)
}
}
And in the ./views folder I have index.html, index.html, footer.html
{{define "header"}}<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>{{end}}
{{define "index"}}{{template "header" . }}
<div>F1: {{.Field1}}</div>
<div>F2: {{.Field2}}</div>
<div>F3: {{.Field3}}</div>
{{template "footer"}}{{end}}
{{define "footer"}}</body></html>{{end}}
The current output is:
F1: Some text<br/>More text
F2: Some text<br/>More text
F3: Some text&lt;br/&gt;More text
The expected outcome is a line break like:
Some text
More text
I tried the following:
htmlBRTag := "<br/>"
b = "Some text." +htmlBRTag+ "More text"
Page.Body = template.HTMLEscapeString(b)
The text in the template becomes:
Some text.&lt;br/&gt;More text
答案1
得分: 1
你可以考虑使用正则表达式来替换所有的换行符"\n"为"
"。
代码如下:
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`(?m)\n`)
var substitution = "<br/>"
var str = `here is some text
that have
newline characters`
fmt.Println(re.ReplaceAllString(str, substitution))
}
你可以在这里尝试使用正则表达式:https://regex101.com/codegen?language=golang
英文:
You may want to consider using a regex expression that simply replaces all of the \n's with <br/>
To do that, your code would look like this
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`(?m)\n`)
var substitution = "<br/>"
var str = `here is some text
that have
newline characters`
fmt.Println(re.ReplaceAllString(str, substitution))
}
you can play around with regex here: https://regex101.com/codegen?language=golang
答案2
得分: 1
感谢您添加示例代码,这样更容易理解您的问题。不过,您的示例代码仍然包含了很多不必要的代码,所以我将使用这个更简单的代码来回答(代码越简单越好)。
请注意,当前的输出实际上是:
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>
<div>F1: Some text<br/>More text</div>
<div>F2: Some text<br/>More text</div>
<div>F3: Some text&lt;br/&gt;More text</div>
</body></html>
您在问题中包含的输出似乎是浏览器显示的内容。浏览器解析接收到的HTML并将其显示出来 - 因此<div>F1: Some text&lt;br/&gt;More text</div>
在浏览器中显示为F1: Some text<br/>More text
(<br/>
是显示的文本,而不是HTML元素<br/>
)。
当浏览器处理HTML时,任何转义字符都会被取消转义(例如&lt;
变为<
)。使用转义字符的原因是防止浏览器将其解析为HTML元素(例如<br>
)。如果您想要换行,输出中需要包含未转义的<br/>
作为原始文本。
Go模板会自动转义传入的字符串中的一系列字符。这是出于安全考虑;否则,用户可能会提交一个带有<script>..</script>
的字符串,如果将其发送到另一个用户的浏览器中,可能会运行一个可能做坏事的脚本!
如果您确信传入的文本是干净的,那么可以使用template.HTML
类型告诉模板引擎您信任这个字符串,例如data.Field4 = template.HTML("Some text 55" + htmlBreak + "More text")
。
以下是一个完整的示例(playground):
package main
import (
"html/template"
"io"
"net/http"
"net/http/httptest"
"os"
)
type Data struct {
Field1 string
Field2 string
Field3 string
Field4 template.HTML
}
var tmpl *template.Template
func main() {
htmlBreak := "<br/>"
data := Data{}
data.Field1 = "Some text<br/>More text"
data.Field2 = "Some text" + htmlBreak + "More text"
data.Field3 = template.HTMLEscapeString(data.Field2)
data.Field4 = template.HTML("Some text 55" + htmlBreak + "More text")
var err error
tmpl, err := template.New("index").Parse(`{{define "header"}}<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>{{end}}
{{define "index"}}{{template "header" . }}
<div>F1: {{.Field1}}</div>
<div>F2: {{.Field2}}</div>
<div>F3: {{.Field3}}</div>
<div>F3: {{.Field4}}</div>
{{template "footer"}}{{end}}
{{define "footer"}}</body></html>{{end}}
`)
// tmpl, err = template.ParseGlob("views/*")
if err != nil {
panic(err.Error())
}
// Now run the template (normally done in a handler)
w := httptest.NewRecorder()
if err = tmpl.ExecuteTemplate(w, "index", data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
w.Flush()
io.Copy(os.Stdout, w.Result().Body)
}
输出结果为:
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>
<div>F1: Some text<br/>More text</div>
<div>F2: Some text<br/>More text</div>
<div>F3: Some text&lt;br/&gt;More text</div>
<div>F3: Some text 55<br/>More text</div>
</body></html>
请注意新行中的<br/>
,浏览器将其显示为换行符。
英文:
Thank you for adding the example code; this makes it much easier to understand your issue. However your example still includes a lot of unnecessary code so I'll answer using this (the simpler the code the better).
Note that this answer matches my comment but as you have included an example its easier to spell it out in a way that you are more likely to understand.
The current output is actually:
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>
<div>F1: Some text&lt;br/&gt;More text</div>
<div>F2: Some text&lt;br/&gt;More text</div>
<div>F3: Some text&amp;lt;br/&amp;gt;More text</div>
</body></html>
The output that you have included in your question appears to be what the browser is displaying. The browser parses the HTML sent to it and displays it - so <div>F1: Some text&lt;br/&gt;More text</div>
becomes F1: Some text<br/>More text
when viewed in a browser (the <br/>
is text that is displayed; not the HTML element <br/>
).
When the browser processes the HTML any escaped characters are unescaped (e.g. &lt;
becomes <
). The reason that escaped characters are used is to prevent the browser from parsing them as HTML elements (e.g. <br>
). If you want a line break then the output needs to include <br/>
as raw text (not escaped).
Go templates automatically escape a range of characters in strings passed in as parameters. This is done for security; otherwise a user might be able to submit a string with <script>..</script>
and if you send that to another users browser it may end up running a script that could do nasty things!
If you are SURE that the text you are passing in is clean then you can use the type template.HTML
to tell the template engine that you trust this string e.g. data.Field4 = template.HTML("Some text 55" + htmlBreak + "More text")
.
Following is a full example (playground):
package main
import (
"html/template"
"io"
"net/http"
"net/http/httptest"
"os"
)
type Data struct {
Field1 string
Field2 string
Field3 string
Field4 template.HTML
}
var tmpl *template.Template
func main() {
htmlBreak := "<br/>"
data := Data{}
data.Field1 = "Some text<br/>More text"
data.Field2 = "Some text" + htmlBreak + "More text"
data.Field3 = template.HTMLEscapeString(data.Field2)
data.Field4 = template.HTML("Some text 55" + htmlBreak + "More text")
var err error
tmpl, err := template.New("index").Parse(`{{define "header"}}<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>{{end}}
{{define "index"}}{{template "header" . }}
<div>F1: {{.Field1}}</div>
<div>F2: {{.Field2}}</div>
<div>F3: {{.Field3}}</div>
<div>F3: {{.Field4}}</div>
{{template "footer"}}{{end}}
{{define "footer"}}</body></html>{{end}}
`)
// tmpl, err = template.ParseGlob("views/*")
if err != nil {
panic(err.Error())
}
// Now run the template (normally done in a handler)
w := httptest.NewRecorder()
if err = tmpl.ExecuteTemplate(w, "index", data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
w.Flush()
io.Copy(os.Stdout, w.Result().Body)
}
The output is:
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>
<div>F1: Some text&lt;br/&gt;More text</div>
<div>F2: Some text&lt;br/&gt;More text</div>
<div>F3: Some text&amp;lt;br/&amp;gt;More text</div>
<div>F3: Some text 55<br/>More text</div>
</body></html>
Note the <br/>
in the new line; the browser will display this as a break.
答案3
得分: 0
你的问题有点模糊,但我认为你可能正在寻找名为HTMLEscapeString(s)
的函数。
HTMLEscapeString返回纯文本数据s的转义HTML等效字符串。
https://pkg.go.dev/html/template@go1.17.2#HTMLEscapeString
英文:
Your question is a little vague, but I believe you may be looking for the function named HTMLEscapeString(s)
.
HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论