Compare commits
7 Commits
6ea200aa64
...
9a1596e932
| Author | SHA1 | Date | |
|---|---|---|---|
|
9a1596e932
|
|||
|
5ce1ec676c
|
|||
|
361f068232
|
|||
|
0281e7ac20
|
|||
|
997be04fc1
|
|||
|
67d255df68
|
|||
|
ad84857ea7
|
@@ -1,20 +1,30 @@
|
|||||||
|
version: "2"
|
||||||
run:
|
run:
|
||||||
timeout: 5m
|
|
||||||
modules-download-mode: readonly
|
modules-download-mode: readonly
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
default: none
|
||||||
enable:
|
enable:
|
||||||
- errcheck
|
- errcheck
|
||||||
- goimports
|
|
||||||
- gofumpt
|
|
||||||
- revive # golint
|
|
||||||
- gosimple
|
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
|
- revive
|
||||||
- staticcheck
|
- staticcheck
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
issues:
|
issues:
|
||||||
exclude-use-default: false
|
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
max-same-issues: 0
|
max-same-issues: 0
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofumpt
|
||||||
|
- goimports
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
|||||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1734424634,
|
"lastModified": 1760878510,
|
||||||
"narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=",
|
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "d3c42f187194c26d9f0309a8ecc469d6c878ce33",
|
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
283
xtemplate/hot.go
Normal file
283
xtemplate/hot.go
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
package xtemplate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
htmltemplate "html/template"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"slices"
|
||||||
|
"text/template"
|
||||||
|
"text/template/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewHot[T template.Template | htmltemplate.Template](name string) *HotTemplate {
|
||||||
|
return Hot(New[T](name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Hot(t Template) *HotTemplate {
|
||||||
|
return &HotTemplate{template: t}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HotTemplate struct {
|
||||||
|
template Template
|
||||||
|
err error
|
||||||
|
methodQueue []struct {
|
||||||
|
name methodName
|
||||||
|
args []any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Template = (*HotTemplate)(nil)
|
||||||
|
|
||||||
|
func (t *HotTemplate) AddParseTree(name string, tree *parse.Tree) (Template, error) {
|
||||||
|
return t.queue(methodAddParseTree, []any{name, tree})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Clone() (Template, error) {
|
||||||
|
return t.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) DefinedTemplates() string {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return temp.DefinedTemplates()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Delims(left, right string) Template {
|
||||||
|
t, _ = t.queue(methodDelims, []any{left, right})
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Execute(wr io.Writer, data any) error {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Join(ErrHotRun, err)
|
||||||
|
}
|
||||||
|
return temp.Execute(wr, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) ExecuteTemplate(wr io.Writer, name string, data any) error {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Join(ErrHotRun, err)
|
||||||
|
}
|
||||||
|
return temp.ExecuteTemplate(wr, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Funcs(funcMap template.FuncMap) Template {
|
||||||
|
t, _ = t.queue(methodFuncs, funcMap)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Lookup(name string) Template {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return temp.Lookup(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Name() string {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return temp.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) New(name string) Template {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return Hot(temp.New(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Option(opt ...string) Template {
|
||||||
|
t, _ = t.queue(methodOption, opt)
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Parse(text string) (Template, error) {
|
||||||
|
return t.queue(methodParse, text)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) ParseFS(fs fs.FS, patterns ...string) (Template, error) {
|
||||||
|
return t.queue(methodParseFS, fs, patterns)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) ParseFiles(filenames ...string) (Template, error) {
|
||||||
|
return t.queue(methodParseFiles, filenames)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) ParseGlob(pattern string) (Template, error) {
|
||||||
|
return t.queue(methodParseGlob, pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) Templates() []Template {
|
||||||
|
temp, err := t.run()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ts := temp.Templates()
|
||||||
|
hts := make([]Template, len(ts))
|
||||||
|
for i := range ts {
|
||||||
|
hts[i] = Hot(ts[i])
|
||||||
|
}
|
||||||
|
return hts
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) queue(method methodName, args ...any) (*HotTemplate, error) {
|
||||||
|
tc, err := t.clone()
|
||||||
|
if err != nil {
|
||||||
|
// HACK: Storing the error so it can be returned on methods that can
|
||||||
|
t.err = errors.Join(ErrHotQueue, err)
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
tc.methodQueue = append(t.methodQueue, struct {
|
||||||
|
name methodName
|
||||||
|
args []any
|
||||||
|
}{
|
||||||
|
name: method,
|
||||||
|
args: args,
|
||||||
|
})
|
||||||
|
return tc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) clone() (*HotTemplate, error) {
|
||||||
|
temp, err := t.template.Clone()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("HotTemplate: unable to clone template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HotTemplate{
|
||||||
|
template: temp,
|
||||||
|
methodQueue: slices.Clone(t.methodQueue),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *HotTemplate) run() (Template, error) {
|
||||||
|
if t.err != nil {
|
||||||
|
return t, fmt.Errorf("HotTemplate: template has a past error: %w", t.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
temp, err := t.template.Clone()
|
||||||
|
if err != nil {
|
||||||
|
return temp, fmt.Errorf("HotTemplate: unable to clone template: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, method := range t.methodQueue {
|
||||||
|
switch method.name {
|
||||||
|
case methodAddParseTree:
|
||||||
|
name, ok := method.args[0].(string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
tree, ok := method.args[1].(*parse.Tree)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: second argument is not of type *parse.Tree")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp, err = temp.AddParseTree(name, tree)
|
||||||
|
|
||||||
|
case methodDelims:
|
||||||
|
left, ok := method.args[0].(string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
right, ok := method.args[1].(string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: second argument is not of type string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp = temp.Delims(left, right)
|
||||||
|
|
||||||
|
case methodFuncs:
|
||||||
|
funcMap, ok := method.args[0].(template.FuncMap)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type template.FuncMap")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp = temp.Funcs(funcMap)
|
||||||
|
|
||||||
|
case methodOption:
|
||||||
|
opt, ok := method.args[0].([]string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type []string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp = temp.Option(opt...)
|
||||||
|
|
||||||
|
case methodParse:
|
||||||
|
text, ok := method.args[0].(string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp, err = temp.Parse(text)
|
||||||
|
|
||||||
|
case methodParseFS:
|
||||||
|
fs, ok := method.args[0].(fs.FS)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type fs.FS")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
patterns, ok := method.args[0].([]string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: second argument is not of type []string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp, err = temp.ParseFS(fs, patterns...)
|
||||||
|
|
||||||
|
case methodParseFiles:
|
||||||
|
filenames, ok := method.args[0].([]string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type []string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp, err = temp.ParseFiles(filenames...)
|
||||||
|
|
||||||
|
case methodParseGlob:
|
||||||
|
pattern, ok := method.args[0].(string)
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("HotTemplate: first argument is not of type string")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
temp, err = temp.ParseGlob(pattern)
|
||||||
|
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("HotTemplate: method %q does not exist", method.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return temp, fmt.Errorf("HotTemplate: failed to run method %q with arguments %v: %w",
|
||||||
|
method.name, method.args, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
methodAddParseTree methodName = "AddParseTree"
|
||||||
|
methodDelims methodName = "Delims"
|
||||||
|
methodFuncs methodName = "Funcs"
|
||||||
|
methodOption methodName = "Option"
|
||||||
|
methodParse methodName = "Parse"
|
||||||
|
methodParseFS methodName = "ParseFS"
|
||||||
|
methodParseFiles methodName = "ParseFiles"
|
||||||
|
methodParseGlob methodName = "ParseGlob"
|
||||||
|
)
|
||||||
|
|
||||||
|
type methodName string
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrHotRun = errors.New("HotTemplate: unable to run queued methods")
|
||||||
|
ErrHotQueue = errors.New("HotTemplate: unable to queue method")
|
||||||
|
)
|
||||||
89
xtemplate/html.go
Normal file
89
xtemplate/html.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package xtemplate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"text/template/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
type htmlTemplate struct {
|
||||||
|
html *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Template = (*htmlTemplate)(nil)
|
||||||
|
|
||||||
|
func (t *htmlTemplate) AddParseTree(name string, tree *parse.Tree) (Template, error) {
|
||||||
|
temp, err := t.html.AddParseTree(name, tree)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Clone() (Template, error) {
|
||||||
|
temp, err := t.html.Clone()
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Delims(left, right string) Template {
|
||||||
|
return &htmlTemplate{t.html.Delims(left, right)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) DefinedTemplates() string {
|
||||||
|
return t.html.DefinedTemplates()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Execute(wr io.Writer, data any) error {
|
||||||
|
return t.html.Execute(wr, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) ExecuteTemplate(wr io.Writer, name string, data any) error {
|
||||||
|
return t.html.ExecuteTemplate(wr, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Funcs(funcMap template.FuncMap) Template {
|
||||||
|
return &htmlTemplate{t.html.Funcs(funcMap)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Lookup(name string) Template {
|
||||||
|
return &htmlTemplate{t.html.Lookup(name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Name() string {
|
||||||
|
return t.html.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) New(name string) Template {
|
||||||
|
return &htmlTemplate{t.html.New(name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Option(opt ...string) Template {
|
||||||
|
return &htmlTemplate{t.html.Option(opt...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Parse(text string) (Template, error) {
|
||||||
|
temp, err := t.html.Parse(text)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) ParseFS(fs fs.FS, patterns ...string) (Template, error) {
|
||||||
|
temp, err := t.html.ParseFS(fs, patterns...)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) ParseFiles(filenames ...string) (Template, error) {
|
||||||
|
temp, err := t.html.ParseFiles(filenames...)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) ParseGlob(pattern string) (Template, error) {
|
||||||
|
temp, err := t.html.ParseGlob(pattern)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *htmlTemplate) Templates() []Template {
|
||||||
|
htmltemps := t.html.Templates()
|
||||||
|
temps := make([]Template, len(htmltemps))
|
||||||
|
for i := range len(temps) {
|
||||||
|
temps[i] = &htmlTemplate{htmltemps[i]}
|
||||||
|
}
|
||||||
|
return temps
|
||||||
|
}
|
||||||
89
xtemplate/text.go
Normal file
89
xtemplate/text.go
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package xtemplate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"text/template"
|
||||||
|
"text/template/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
type textTemplate struct {
|
||||||
|
text *template.Template
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ Template = (*textTemplate)(nil)
|
||||||
|
|
||||||
|
func (t *textTemplate) AddParseTree(name string, tree *parse.Tree) (Template, error) {
|
||||||
|
temp, err := t.text.AddParseTree(name, tree)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Clone() (Template, error) {
|
||||||
|
temp, err := t.text.Clone()
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Delims(left, right string) Template {
|
||||||
|
return &textTemplate{t.text.Delims(left, right)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) DefinedTemplates() string {
|
||||||
|
return t.text.DefinedTemplates()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Execute(wr io.Writer, data any) error {
|
||||||
|
return t.text.Execute(wr, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) ExecuteTemplate(wr io.Writer, name string, data any) error {
|
||||||
|
return t.text.ExecuteTemplate(wr, name, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Funcs(funcMap template.FuncMap) Template {
|
||||||
|
return &textTemplate{t.text.Funcs(funcMap)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Lookup(name string) Template {
|
||||||
|
return &textTemplate{t.text.Lookup(name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Name() string {
|
||||||
|
return t.text.Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) New(name string) Template {
|
||||||
|
return &textTemplate{t.text.New(name)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Option(opt ...string) Template {
|
||||||
|
return &textTemplate{t.text.Option(opt...)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Parse(text string) (Template, error) {
|
||||||
|
temp, err := t.text.Parse(text)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) ParseFS(fs fs.FS, patterns ...string) (Template, error) {
|
||||||
|
temp, err := t.text.ParseFS(fs, patterns...)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) ParseFiles(filenames ...string) (Template, error) {
|
||||||
|
temp, err := t.text.ParseFiles(filenames...)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) ParseGlob(pattern string) (Template, error) {
|
||||||
|
temp, err := t.text.ParseGlob(pattern)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *textTemplate) Templates() []Template {
|
||||||
|
texttemps := t.text.Templates()
|
||||||
|
temps := make([]Template, len(texttemps))
|
||||||
|
for i := range len(temps) {
|
||||||
|
temps[i] = &textTemplate{texttemps[i]}
|
||||||
|
}
|
||||||
|
return temps
|
||||||
|
}
|
||||||
94
xtemplate/xtemplate.go
Normal file
94
xtemplate/xtemplate.go
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package xtemplate
|
||||||
|
|
||||||
|
import (
|
||||||
|
htmltemplate "html/template"
|
||||||
|
"io"
|
||||||
|
"io/fs"
|
||||||
|
"text/template"
|
||||||
|
"text/template/parse"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Must(t Template, err error) Template {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
func New[T template.Template | htmltemplate.Template](name string) Template {
|
||||||
|
var t T
|
||||||
|
switch any(t).(type) {
|
||||||
|
case template.Template:
|
||||||
|
return &textTemplate{template.New(name)}
|
||||||
|
case htmltemplate.Template:
|
||||||
|
return &htmlTemplate{htmltemplate.New(name)}
|
||||||
|
default:
|
||||||
|
panic("Incorrect T type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseFS[T template.Template | htmltemplate.Template](fs fs.FS, patterns ...string) (Template, error) {
|
||||||
|
var t T
|
||||||
|
switch any(t).(type) {
|
||||||
|
case template.Template:
|
||||||
|
temp, err := template.ParseFS(fs, patterns...)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
case htmltemplate.Template:
|
||||||
|
temp, err := htmltemplate.ParseFS(fs, patterns...)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
default:
|
||||||
|
panic("Incorrect T type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseFiles[T template.Template | htmltemplate.Template](filenames ...string) (Template, error) {
|
||||||
|
var t T
|
||||||
|
switch any(t).(type) {
|
||||||
|
case template.Template:
|
||||||
|
temp, err := template.ParseFiles(filenames...)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
case htmltemplate.Template:
|
||||||
|
temp, err := htmltemplate.ParseFiles(filenames...)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
default:
|
||||||
|
panic("Incorrect T type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseGlob[T template.Template | htmltemplate.Template](pattern string) (Template, error) {
|
||||||
|
var t T
|
||||||
|
switch any(t).(type) {
|
||||||
|
case template.Template:
|
||||||
|
temp, err := template.ParseGlob(pattern)
|
||||||
|
return &textTemplate{temp}, err
|
||||||
|
case htmltemplate.Template:
|
||||||
|
temp, err := htmltemplate.ParseGlob(pattern)
|
||||||
|
return &htmlTemplate{temp}, err
|
||||||
|
default:
|
||||||
|
panic("Incorrect T type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Template interface {
|
||||||
|
AddParseTree(name string, tree *parse.Tree) (Template, error)
|
||||||
|
Clone() (Template, error)
|
||||||
|
DefinedTemplates() string
|
||||||
|
Delims(left, right string) Template
|
||||||
|
Funcs(funcMap template.FuncMap) Template
|
||||||
|
Lookup(name string) Template
|
||||||
|
Name() string
|
||||||
|
New(name string) Template
|
||||||
|
Option(opt ...string) Template
|
||||||
|
Parse(text string) (Template, error)
|
||||||
|
ParseFS(fs fs.FS, patterns ...string) (Template, error)
|
||||||
|
ParseFiles(filenames ...string) (Template, error)
|
||||||
|
ParseGlob(pattern string) (Template, error)
|
||||||
|
Templates() []Template
|
||||||
|
|
||||||
|
Templater
|
||||||
|
}
|
||||||
|
|
||||||
|
type Templater interface {
|
||||||
|
Execute(wr io.Writer, data any) error
|
||||||
|
ExecuteTemplate(wr io.Writer, name string, data any) error
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user