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
|
package frontend
import (
"html/template"
"net/http"
"os"
"path/filepath"
"strings"
)
// Action ist die Aktion auf einer Card.
type Action struct {
Name string
Link string
Target string
Disabled bool
}
// Card ist eine Karte im Materialize-Design.
type Card struct {
Title string
Image string
Description string
Size string
Actions []Action
}
// Renderer rendert Seiten.
type Renderer struct {
templates *template.Template
defaultData map[string]interface{}
}
// RangePair für Range-Dingens. Damit man die ID weiterhin accessen kann.
type RangePair struct {
Index int
Value interface{}
}
// DefaultData gibt die Standard-Daten für die Views zurück. Das ist immer eine Kopie weil Reasons.
func (r *Renderer) DefaultData() map[string]interface{} {
d := make(map[string]interface{})
for k, v := range r.defaultData {
d[k] = v
}
return d
}
// SetDefaultData updated die standarddaten
func (r *Renderer) SetDefaultData(data map[string]interface{}) {
r.defaultData = data
}
// New erstellt einen neuen Renderer und sucht alle Templates aus dem gegebenen pfad.
func New(path string, functions map[string]interface{}) *Renderer {
// Custom Template Funcs
funcMap := template.FuncMap{
"html": func(in string) template.HTML {
return template.HTML(in)
},
"add": func(a, b int) int {
return a + b
},
"sub": func(a, b int) int {
return a - b
},
"makeRangePair": func(idx int, value interface{}) RangePair {
return RangePair{idx, value}
},
"map": func(values ...interface{}) map[string]interface{} {
m := make(map[string]interface{}, len(values)/2)
for i := 0; i < len(values); i += 2 {
key, _ := values[i].(string)
m[key] = values[i+1]
}
return m
},
"makeObject": func(name string, existing interface{}, newKey string, newData interface{}) map[string]interface{} {
d := make(map[string]interface{})
d[name] = existing
d[newKey] = newData
return d
},
}
for k, v := range functions {
funcMap[k] = v
}
files := make([]string, 0)
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if info.IsDir() || !strings.HasSuffix(path, ".html") {
return nil
}
files = append(files, path)
return nil
})
r := &Renderer{
template.Must(template.New("").Funcs(funcMap).ParseFiles(files...)),
make(map[string]interface{}),
}
return r
}
// RenderPage rendert eine bestimmte Seite (basierend auf dem Template-Namen) und den gegebenen Daten.
func (r *Renderer) RenderPage(name string, w http.ResponseWriter, data map[string]interface{}) {
// default daten einspeisen
for k, v := range r.defaultData {
if _, ok := data[k]; !ok {
data[k] = v
}
}
err := r.templates.ExecuteTemplate(w, name, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
// RenderLoginPage zeigt die Loginseite an.
func (r *Renderer) RenderLoginPage(w http.ResponseWriter, data map[string]interface{}) {
r.RenderPage("login", w, data)
}
// RenderRegistrationPage zeigt die Registrationsseite an.
func (r *Renderer) RenderRegistrationPage(w http.ResponseWriter, data map[string]interface{}) {
r.RenderPage("register", w, data)
}
// RenderUserSettingsPage zeigt die Einstellungen für den Benutzer an.
func (r *Renderer) RenderUserSettingsPage(w http.ResponseWriter, data map[string]interface{}) {
r.RenderPage("user_settings", w, data)
}
func (r *Renderer) RenderAPICouplePage(w http.ResponseWriter, data map[string]interface{}) {
r.RenderPage("api_couple", w, data)
}
|