Перейти template.ExecuteTemplate включает в себя HTML

go go-templates

23414 просмотра

8 ответа

1299 Репутация автора

Я следовал этому руководству: http://golang.org/doc/articles/wiki/final.go и немного изменил его для своих нужд / желаний. Проблема в том, что я хотел бы поддерживать HTML в шаблонах. Я понимаю, что это риск для безопасности, но сейчас это не проблема.

Результат рендеринга страницы:

<h1>this<strong>is</strong>a test</h1>

Позвольте мне объяснить немного кода:

type Page struct {
    Title string
    Body  []byte
}

Данные, в которых я хотел бы иметь HTML, хранятся в Page.Body. Это тип, []byteкоторый означает, что я не могу (или могу ли я?) Работать, так html/template.HTML(Page.Body)как эта функция ожидает строку.

У меня есть это, которое предварительно отрисовывает шаблоны:

var (
    templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)

И фактическое ExecuteTemplateвыглядит так:

err := templates.ExecuteTemplate(w, tmpl+".html", p)

Где w есть w http.ResponseWriter, tmpl есть tmpl string, а p естьp *Page

Наконец, мой 'view.html'(шаблон) выглядит следующим образом:

<h1>{{.Title}}</h1>
<p>[<a href="/edit/{{.Title}}">edit</a>]</p>
<div>{{printf "%s" .Body}}</div>

Вещи, которые я пробовал:

  • {{printf "%s" .Body | html}} ничего не делает
  • Я включил github.com/russross/blackfriday(процессор Markdown) и запустил, p.Body = blackfriday.MarkdownCommon(p.Body)который правильно преобразует Markdown в HTML, но HTML по-прежнему выводится как сущности.
  • РЕДАКТИРОВАТЬ: я попытался следующий фрагмент кода (я не знаю, почему формат испорчен), и он все еще выводит точно так же.

    var s template.HTML s = template.HTML(p.Body) p.Body = []byte(s)

Любое руководство с благодарностью. Если я в замешательстве, пожалуйста, спросите, и я могу изменить свой вопрос.

Автор: Peter Источник Размещён: 11.08.2013 07:04

Ответы (8)


-1 плюса

61931 Репутация автора

Почему бы не преобразовать в []byteстроку? Вы можете сделать это так:

str := string(page.Body)
Автор: David Grayson Размещён: 11.08.2013 07:35

51 плюса

17373 Репутация автора

Решение

Преобразовать ваш []byteили stringнабрать template.HTML(задокументировано здесь )

p.Body = template.HTML(s) // where s is a string or []byte

Затем в вашем шаблоне просто:

{{.Body}}

Он будет напечатан без побега.

РЕДАКТИРОВАТЬ

Чтобы иметь возможность включать HTML в тело вашей страницы, вам нужно изменить Pageобъявление типа:

type Page struct {
    Title string
    Body  template.HTML
}

затем назначьте ему.

Автор: thwd Размещён: 12.08.2013 11:22

16 плюса

59941 Репутация автора

Посмотрите на тип template.HTML . Он может использоваться для инкапсуляции известного безопасного фрагмента HTML (например, вывода из Markdown). Пакет "html / template" не избежит этого типа.

type Page struct {
    Title string
    Body template.HTML
}

page := &Page{
    Title: "Example",
    Body:  template.HTML(blackfriday.MarkdownCommon([]byte("foo bar")),
}

Я обычно пишу свой собственный func Markdown(text string) html.Templateметод, который вызывает blackfriday с соответствующей конфигурацией и выполняет некоторые преобразования типов. Другой альтернативой может быть также регистрация функции html в парсере шаблонов, которая позволяет вам выводить любое значение без экранирования, выполняя что-то подобное {{html .MySafeStr}}. Код может выглядеть так:

var tmpl = template.Must(template.New("").Funcs(template.FuncMap{
    "html": func(value interface{}) template.HTML {
        return template.HTML(fmt.Sprint(value))
    },
}).ParseFiles("file1.html", "file2.html"))
Автор: tux21b Размещён: 15.08.2013 10:05

1 плюс

42 Репутация автора

Я использую Beego и React.js и несколько часов боролся за то, чтобы запустить парсер JSX. Оказывается, html / template удаляет комментарии, особенно блок js doc / ** @jsx React.DOM * /.

Обошли его, создав специальный метод для ввода комментария как JS и вызова его из шаблона.

// Create a method in your controller (I'm using Beego)
func jsxdoc()(out template.JS) {
    return template.JS(`/** @jsx React.DOM */`)
}

// Add method to your function map available to views
beego.AddFuncMap("jsxdoc", jsxdoc)

// In template
<script type="text/jsx">
    {{ jsxdoc }}
    var CommentBox = React.createClass({
      render: function() {
        return (
          <div class="commentBox">
            Hello, world! I am a CommentBox.
          </div>
        );
      }
    });
    React.renderComponent(
      <CommentBox />,
      document.getElementById('content')
    );
</script>
Автор: user2363571 Размещён: 22.07.2014 02:03

0 плюса

2313 Репутация автора

Для пояснения и гораздо более простого способа передачи HTML в шаблон см.

https://groups.google.com/forum/#!topic/golang-nuts/8L4eDkr5Q84

Просто создайте строку HTML с помощью go и передайте ее в шаблон, например:

Sout := ""
.
.

    Sout += fmt.Sprintf(`<tr><td>%s<td align=center>%.2f<td>%s<td>%s<td>%s<td>%s<td align=center>%d<td align=center>%d
                    <td align=center>%d`, AccountID, amount, remissiondetails, created, begins, ends,
                    freePDFs, freeinformants, freeSDQs)

.
.
    render(w, "templates/Waivers.html", map[string]interface{}{ "Body":template.HTML(Sout), })
Автор: user2099484 Размещён: 13.01.2017 11:13

9 плюса

10505 Репутация автора

Я создал пользовательскую функцию для шаблона следующим образом:

func noescape(str string) template.HTML {
    return template.HTML(str)
}

var fn = template.FuncMap{
    "noescape": noescape,
}

Тогда по вашему шаблону:

{{ noescape $x.Body }}
Автор: majidarif Размещён: 05.02.2017 05:40

1 плюс

1053 Репутация автора

Вот подход, который не требует каких-либо изменений в ваших существующих структурах и очень минимальных, аддитивных изменений в ваших шаблонах:

Измените эти строки:

var (
    templates = template.Must(template.ParseFiles("tmpl/edit.html", "tmpl/view.html"))
)

к этому (включите funcmap с функцией, которая будет выводить неэкранированный HTML):

var templates = template.Must(template.New("main").Funcs(template.FuncMap{
    "safeHTML": func(b []byte) template.HTML {
        return template.HTML(b)
    },
}).ParseFiles("tmpl/edit.html", "tmpl/view.html"))

А затем просто измените ваш шаблон HTML из этого:

<div>{{printf "%s" .Body}}</div>

к этому (используйте вашу новую функцию):

<div>{{ .Body | safeHTML }}</div>

Намного легче!

Автор: Astockwell Размещён: 27.05.2017 10:36

0 плюса

2144 Репутация автора

В моем случае (когда я заполняю представление structсписком Activity), мне пришлось изменить свойство Message stringна Message template.HTML. Затем при установке значения свойства я могу позвонить activity.Message = template.HTML("The <b>HTML</b>").

Автор: crmepham Размещён: 02.11.2019 06:25
Вопросы из категории :
32x32