forked from hoisie/mustache
-
Notifications
You must be signed in to change notification settings - Fork 80
/
partials.go
101 lines (83 loc) · 2.51 KB
/
partials.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
package mustache
import (
"os"
"path"
"regexp"
)
// PartialProvider comprises the behaviors required of a struct to be able to provide partials to the mustache rendering
// engine.
type PartialProvider interface {
// Get accepts the name of a partial and returns the parsed partial, if it could be found; a valid but empty
// template, if it could not be found; or nil and error if an error occurred (other than an inability to find
// the partial).
Get(name string) (string, error)
}
// FileProvider implements the PartialProvider interface by providing partials drawn from a filesystem. When a partial
// named `NAME` is requested, FileProvider searches each listed path for a file named as `NAME` followed by any of the
// listed extensions. The default for `Paths` is to search the current working directory. The default for `Extensions`
// is to examine, in order, no extension; then ".mustache"; then ".stache".
type FileProvider struct {
Paths []string
Extensions []string
}
// Get accepts the name of a partial and returns the parsed partial.
func (fp *FileProvider) Get(name string) (string, error) {
var filename string
var paths []string
if fp.Paths != nil {
paths = fp.Paths
} else {
paths = []string{""}
}
var exts []string
if fp.Extensions != nil {
exts = fp.Extensions
} else {
exts = []string{"", ".mustache", ".stache"}
}
for _, p := range paths {
for _, e := range exts {
name := path.Join(p, name+e)
f, err := os.Open(name)
if err == nil {
filename = name
f.Close()
break
}
}
}
if filename == "" {
return "", nil
}
data, err := os.ReadFile(filename)
if err != nil {
return "", err
}
return string(data), nil
}
var _ PartialProvider = (*FileProvider)(nil)
// StaticProvider implements the PartialProvider interface by providing partials drawn from a map, which maps partial
// name to template contents.
type StaticProvider struct {
Partials map[string]string
}
// Get accepts the name of a partial and returns the parsed partial.
func (sp *StaticProvider) Get(name string) (string, error) {
if sp.Partials != nil {
if data, ok := sp.Partials[name]; ok {
return data, nil
}
}
return "", nil
}
var _ PartialProvider = (*StaticProvider)(nil)
func getPartials(partials PartialProvider, name, indent string) (*Template, error) {
data, err := partials.Get(name)
if err != nil {
return nil, err
}
// indent non empty lines
r := regexp.MustCompile(`(?m:^(.+)$)`)
data = r.ReplaceAllString(data, indent+"$1")
return ParseStringPartials(data, partials)
}