aboutsummaryrefslogtreecommitdiff
path: root/frontend/renderer.go
blob: 7d3a161c4e9270006c0c0332fba7bacf6c533960 (plain)
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)
}