diff options
Diffstat (limited to 'echo/template_renderer.go')
-rw-r--r-- | echo/template_renderer.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/echo/template_renderer.go b/echo/template_renderer.go new file mode 100644 index 0000000..0bafd92 --- /dev/null +++ b/echo/template_renderer.go | |||
@@ -0,0 +1,114 @@ | |||
1 | package echo | ||
2 | |||
3 | import ( | ||
4 | "html/template" | ||
5 | "io" | ||
6 | "net/http" | ||
7 | "os" | ||
8 | "path/filepath" | ||
9 | |||
10 | "github.com/labstack/echo/v4" | ||
11 | ) | ||
12 | |||
13 | type TemplateChecker interface { | ||
14 | HaveTemplate(echo.Context, string) bool | ||
15 | } | ||
16 | |||
17 | type TemplateRenderer struct { | ||
18 | path string | ||
19 | glob string | ||
20 | funcs template.FuncMap | ||
21 | cache *template.Template | ||
22 | } | ||
23 | |||
24 | func NewTemplateRenderer(path, glob string, funcs template.FuncMap) (*TemplateRenderer, error) { | ||
25 | var err error | ||
26 | |||
27 | r := &TemplateRenderer{path: path, glob: glob, funcs: funcs} | ||
28 | r.cache, err = r.loadTemplates() | ||
29 | if err != nil { | ||
30 | return nil, err | ||
31 | } | ||
32 | |||
33 | return r, nil | ||
34 | } | ||
35 | |||
36 | func (r *TemplateRenderer) loadTemplates() (*template.Template, error) { | ||
37 | t := template.New("").Funcs(r.funcs) | ||
38 | |||
39 | err := filepath.Walk(r.path, func(path string, info os.FileInfo, err error) error { | ||
40 | if err != nil { | ||
41 | return err | ||
42 | } | ||
43 | |||
44 | if !info.IsDir() { | ||
45 | _, fn := filepath.Split(path) | ||
46 | if ok, _ := filepath.Match(r.glob, fn); ok { | ||
47 | fc, err := os.ReadFile(path) | ||
48 | if err != nil { | ||
49 | return err | ||
50 | } | ||
51 | |||
52 | rp, err := filepath.Rel(r.path, path) | ||
53 | if err != nil { | ||
54 | return err | ||
55 | } | ||
56 | |||
57 | _, err = t.New(rp).Parse(string(fc)) | ||
58 | if err != nil { | ||
59 | return err | ||
60 | } | ||
61 | } | ||
62 | } | ||
63 | |||
64 | return nil | ||
65 | }) | ||
66 | if err != nil { | ||
67 | return nil, err | ||
68 | } | ||
69 | |||
70 | return t, nil | ||
71 | } | ||
72 | |||
73 | func (r *TemplateRenderer) getTemplateCache(ctx echo.Context) (*template.Template, error) { | ||
74 | var err error | ||
75 | |||
76 | tc := r.cache | ||
77 | if ctx.Echo().Debug { | ||
78 | tc, err = r.loadTemplates() | ||
79 | if err != nil { | ||
80 | return nil, err | ||
81 | } | ||
82 | } | ||
83 | |||
84 | return tc, nil | ||
85 | } | ||
86 | |||
87 | func (r *TemplateRenderer) Render(w io.Writer, name string, data interface{}, ctx echo.Context) error { | ||
88 | tc, err := r.getTemplateCache(ctx) | ||
89 | if err != nil { | ||
90 | return err | ||
91 | } | ||
92 | |||
93 | if tc.Lookup(name) == nil { | ||
94 | return echo.NewHTTPError(http.StatusNotFound, "Page not found") | ||
95 | } | ||
96 | |||
97 | if err := tc.ExecuteTemplate(w, name, data); err != nil { | ||
98 | return err | ||
99 | } | ||
100 | |||
101 | return nil | ||
102 | } | ||
103 | |||
104 | func (r *TemplateRenderer) HaveTemplate(ctx echo.Context, name string) bool { | ||
105 | tc, err := r.getTemplateCache(ctx) | ||
106 | if err != nil { | ||
107 | return false | ||
108 | } | ||
109 | |||
110 | return tc.Lookup(name) != nil | ||
111 | } | ||
112 | |||
113 | var _ echo.Renderer = (*TemplateRenderer)(nil) | ||
114 | var _ TemplateChecker = (*TemplateRenderer)(nil) | ||