Мне интересно, можно ли использовать пользовательскую функцию в качестве блока шаблонов с шаблонами Golang. В приведенном ниже коде показан пример.
{{ custom_func . }}
This is content that "custom_func" should do something with.
{{ end }}
Вариант использования немного своеобразный и нестандартный. По сути, я хочу, чтобы автор шаблона мог передавать большой блок текста, где соблюдаются символы новой строки и т. д., и чтобы весь этот блок текста передавался в функцию. Я мог бы сделать что-то вроде:
{{ custom_func "This is a lot of text\n with many lines etc." }}
Но это не очень удобно для автора шаблона. Конечная цель состоит в том, чтобы они написали что-то вроде этого:
Author is writing something normal...
{{ note }}
But would like to wrap this content as a "note".
Which when passed to the "note" function, will wrap the content with appropriate divs etc.
{{ end }}
По сути, я пытаюсь провести эксперимент, чтобы увидеть, смогу ли я получить контент, подобный «уценке/реструктурированному тексту», с помощью шаблонов чистого перехода. Пока это в основном эксперимент.
В конце концов мне, вероятно, придется написать для этого правильный анализатор PEG, но я хочу сначала посмотреть, возможно ли это.
@andre, можешь привести более наглядный пример? Какого варианта использования вы пытаетесь достичь?
хочешь calhoun.io/intro-to-templates-p3-functions ?
@thanatonian2311 Я добавил больше деталей, объясняющих вариант использования
Вы можете использовать пару функций func open(tag string) string
и func close(tag string) string
, которые создают открывающий и закрывающий теги. Используйте их в шаблоне как {{open "node"}}Some Text{{close "note"}}
Строковые аргументы функций могут быть заключены как в двойные кавычки "
, так и в обратные кавычки `.
Строковые литералы, завернутые в обратные кавычки в шаблонах, называются необработанными строковыми константами, и они работают как необработанные строковые литералы в исходном коде Go: могут включать новые строки (и не могут содержать escape-последовательности).
Так что возможно то, что вы хотите, если вы используете обратные кавычки для аргумента.
Например, a.tmpl
:
START
{{ note `a
b\t
c
d`}}
END
Приложение для загрузки и выполнения шаблона:
t := template.Must(template.New("").Funcs(template.FuncMap{
"note": func(s string) string { return "<note>\n" + s + "\n</note>" },
}).ParseFiles("a.tmpl"))
if err := t.ExecuteTemplate(os.Stdout, "a.tmpl", nil); err != nil {
panic(err)
}
Это выведет:
START
<note>
a
b\t
c
d
</note>
END
Это немного сложно, если вы определяете шаблон в своем исходном коде Go, так как если вы используете обратные кавычки для текста шаблона (потому что вы хотите написать несколько строк), вы не можете вставлять обратные кавычки в необработанный строковый литерал. Вы должны сломать литерал и соединить обратные кавычки.
Пример выполнения этого в исходном файле Go:
func main() {
t := template.Must(template.New("").Funcs(template.FuncMap{
"note": func(s string) string { return "<note>\n" + s + "\n</note>" },
}).Parse(src))
if err := t.Execute(os.Stdout, nil); err != nil {
panic(err)
}
}
const src = `START
{{ note ` + "`" + `a
b\t
c
d` + "`" + `}}
END
`
Это выведет то же самое, попробуйте на Go Playground.
Такой подход сработает, да. Меня беспокоит только удобство использования для автора шаблона (который не очень разбирается в технических вопросах). Но спасибо за предложение, оно дает мне много информации и т. д., с которой я могу исследовать и экспериментировать.
Я отмечаю этот ответ как принятый ответ, поскольку он действительно работает довольно хорошо. К сожалению, после множества тестов для моего конкретного варианта использования он не будет идеальным. Мне придется написать правильный анализатор PEG и грамматику.
Вызовы функций ограничены конвейерами, а конвейеры охватываются
{{ }}
. Конвейеры не распространяются на содержимое блока.