-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
133 lines (108 loc) · 3.24 KB
/
config.go
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
// xtemplate extends Go's html/template to be capable enough to define an entire
// server-side application with a directory of Go templates.
package xtemplate
import (
"context"
"fmt"
"html/template"
"io/fs"
"log/slog"
)
func New() (c *Config) {
c = &Config{}
c.Defaults()
return
}
type Config struct {
// The path to the templates directory. Default `templates`.
TemplatesDir string `json:"templates_dir,omitempty" arg:"-t,--template-dir" default:"templates"`
// The FS to load templates from. Overrides TemplatesDir if not nil.
TemplatesFS fs.FS `json:"-" arg:"-"`
// File extension to search for to find template files. Default `.html`.
TemplateExtension string `json:"template_extension,omitempty" arg:"--template-ext" default:".html"`
// Left template action delimiter. Default `{{`.
LDelim string `json:"left,omitempty" arg:"--ldelim" default:"{{"`
// Right template action delimiter. Default `}}`.
RDelim string `json:"right,omitempty" arg:"--rdelim" default:"}}"`
// Whether html templates are minified at load time. Default `true`.
Minify bool `json:"minify,omitempty" arg:"-m,--minify" default:"true"`
// A list of additional custom fields to add to the template dot value
// `{{.}}`.
Dot []DotConfig `json:"dot" arg:"-d,--dot,separate"`
// Additional functions to add to the template execution context.
FuncMaps []template.FuncMap `json:"-" arg:"-"`
// The instance context that is threaded through dot providers and can
// cancel the server. Defaults to `context.Background()`.
Ctx context.Context `json:"-" arg:"-"`
// The default logger. Defaults to `slog.Default()`.
Logger *slog.Logger `json:"-" arg:"-"`
}
// FillDefaults sets default values for unset fields
func (config *Config) Defaults() *Config {
if config.TemplatesDir == "" {
config.TemplatesDir = "templates"
}
if config.TemplateExtension == "" {
config.TemplateExtension = ".html"
}
if config.LDelim == "" {
config.LDelim = "{{"
}
if config.RDelim == "" {
config.RDelim = "}}"
}
if config.Logger == nil {
config.Logger = slog.Default()
}
if config.Ctx == nil {
config.Ctx = context.Background()
}
return config
}
func (c *Config) Options(options ...Option) (*Config, error) {
for _, o := range options {
if err := o(c); err != nil {
return nil, fmt.Errorf("failed to apply xtemplate config option: %w", err)
}
}
return c, nil
}
type Option func(*Config) error
func WithTemplateFS(fs fs.FS) Option {
return func(c *Config) error {
if fs == nil {
return fmt.Errorf("nil fs")
}
c.TemplatesFS = fs
return nil
}
}
func WithLogger(logger *slog.Logger) Option {
return func(c *Config) error {
if logger == nil {
return fmt.Errorf("nil logger")
}
c.Logger = logger
return nil
}
}
func WithFuncMaps(fm ...template.FuncMap) Option {
return func(c *Config) error {
c.FuncMaps = append(c.FuncMaps, fm...)
return nil
}
}
func WithProvider(name string, p DotProvider) Option {
return func(c *Config) error {
for _, d := range c.Dot {
if d.Name == name {
if d.DotProvider != p {
return fmt.Errorf("tried to assign different providers the same name. name: %s; old: %v; new: %v", d.Name, d.DotProvider, p)
}
return nil
}
}
c.Dot = append(c.Dot, DotConfig{Name: name, DotProvider: p})
return nil
}
}