Golang: Пользовательские функции «блока» шаблона?

Мне интересно, можно ли использовать пользовательскую функцию в качестве блока шаблонов с шаблонами 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, но я хочу сначала посмотреть, возможно ли это.

Вызовы функций ограничены конвейерами, а конвейеры охватываются {{ }}. Конвейеры не распространяются на содержимое блока.

Pak Uula 30.10.2022 05:48

@andre, можешь привести более наглядный пример? Какого варианта использования вы пытаетесь достичь?

thanatonian2311 30.10.2022 06:58

хочешь calhoun.io/intro-to-templates-p3-functions ?

mohammad mobasher 30.10.2022 07:27

@thanatonian2311 Я добавил больше деталей, объясняющих вариант использования

Andre 30.10.2022 08:37

Вы можете использовать пару функций func open(tag string) string и func close(tag string) string, которые создают открывающий и закрывающий теги. Используйте их в шаблоне как {{open "node"}}Some Text{{close "note"}}

Pak Uula 30.10.2022 22:02
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
5
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Строковые аргументы функций могут быть заключены как в двойные кавычки ", так и в обратные кавычки `.

Строковые литералы, завернутые в обратные кавычки в шаблонах, называются необработанными строковыми константами, и они работают как необработанные строковые литералы в исходном коде 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.

Такой подход сработает, да. Меня беспокоит только удобство использования для автора шаблона (который не очень разбирается в технических вопросах). Но спасибо за предложение, оно дает мне много информации и т. д., с которой я могу исследовать и экспериментировать.

Andre 31.10.2022 13:44

Я отмечаю этот ответ как принятый ответ, поскольку он действительно работает довольно хорошо. К сожалению, после множества тестов для моего конкретного варианта использования он не будет идеальным. Мне придется написать правильный анализатор PEG и грамматику.

Andre 04.11.2022 21:12

Другие вопросы по теме