476d2547e
김태훈
태마루 시스템 설정 / 업데이트...
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
package multitemplate
import (
"fmt"
"html/template"
"path/filepath"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/render"
)
// DynamicRender type
type DynamicRender map[string]*templateBuilder
var (
_ render.HTMLRender = DynamicRender{}
_ Renderer = DynamicRender{}
)
// NewDynamic is the constructor for Dynamic templates
func NewDynamic() DynamicRender {
return make(DynamicRender)
}
// NewRenderer allows create an agnostic multitemplate renderer
// depending on enabled gin mode
func NewRenderer() Renderer {
if gin.IsDebugging() {
return NewDynamic()
}
return New()
}
// Type of dynamic builder
type builderType int
// Types of dynamic builders
const (
templateType builderType = iota
filesTemplateType
globTemplateType
stringTemplateType
stringFuncTemplateType
filesFuncTemplateType
)
// Builder for dynamic templates
type templateBuilder struct {
buildType builderType
tmpl *template.Template
templateName string
files []string
glob string
templateString string
funcMap template.FuncMap
templateStrings []string
}
func (tb templateBuilder) buildTemplate() *template.Template {
switch tb.buildType {
case templateType:
return tb.tmpl
case filesTemplateType:
return template.Must(template.ParseFiles(tb.files...))
case globTemplateType:
return template.Must(template.ParseGlob(tb.glob))
case stringTemplateType:
return template.Must(template.New(tb.templateName).Parse(tb.templateString))
case stringFuncTemplateType:
tmpl := template.New(tb.templateName).Funcs(tb.funcMap)
for _, ts := range tb.templateStrings {
tmpl = template.Must(tmpl.Parse(ts))
}
return tmpl
case filesFuncTemplateType:
return template.Must(template.New(tb.templateName).Funcs(tb.funcMap).ParseFiles(tb.files...))
default:
panic("Invalid builder type for dynamic template")
}
}
// Add new template
func (r DynamicRender) Add(name string, tmpl *template.Template) {
if tmpl == nil {
panic("template cannot be nil")
}
if len(name) == 0 {
panic("template name cannot be empty")
}
builder := &templateBuilder{templateName: name, tmpl: tmpl}
builder.buildType = templateType
r[name] = builder
}
// AddFromFiles supply add template from files
func (r DynamicRender) AddFromFiles(name string, files ...string) *template.Template {
builder := &templateBuilder{templateName: name, files: files}
builder.buildType = filesTemplateType
r[name] = builder
return builder.buildTemplate()
}
// AddFromGlob supply add template from global path
func (r DynamicRender) AddFromGlob(name, glob string) *template.Template {
builder := &templateBuilder{templateName: name, glob: glob}
builder.buildType = globTemplateType
r[name] = builder
return builder.buildTemplate()
}
// AddFromString supply add template from strings
func (r DynamicRender) AddFromString(name, templateString string) *template.Template {
builder := &templateBuilder{templateName: name, templateString: templateString}
builder.buildType = stringTemplateType
r[name] = builder
return builder.buildTemplate()
}
// AddFromStringsFuncs supply add template from strings
func (r DynamicRender) AddFromStringsFuncs(name string, funcMap template.FuncMap, templateStrings ...string) *template.Template {
builder := &templateBuilder{templateName: name, funcMap: funcMap,
templateStrings: templateStrings}
builder.buildType = stringFuncTemplateType
r[name] = builder
return builder.buildTemplate()
}
// AddFromFilesFuncs supply add template from file callback func
func (r DynamicRender) AddFromFilesFuncs(name string, funcMap template.FuncMap, files ...string) *template.Template {
tname := filepath.Base(files[0])
builder := &templateBuilder{templateName: tname, funcMap: funcMap, files: files}
builder.buildType = filesFuncTemplateType
r[name] = builder
return builder.buildTemplate()
}
// Instance supply render string
func (r DynamicRender) Instance(name string, data interface{}) render.Render {
builder, ok := r[name]
if !ok {
panic(fmt.Sprintf("Dynamic template with name %s not found", name))
}
return render.HTML{
Template: builder.buildTemplate(),
Data: data,
}
}
|