preparations for styling: refactor template rendering #1
|
@ -2,7 +2,6 @@ package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
"officeHours/config"
|
"officeHours/config"
|
||||||
|
@ -149,12 +148,12 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ
|
||||||
id, err := b.officeHourRepo.Add(officeHour)
|
id, err := b.officeHourRepo.Add(officeHour)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
Templates.ExecuteTemplate(w, "addFailure.html", err)
|
b.serveTemplate(w, "addFailure", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
officeHour, _ = b.officeHourRepo.FindById(id)
|
officeHour, _ = b.officeHourRepo.FindById(id)
|
||||||
b.requestRepo.Add(officeHour, models.RequestActivate)
|
b.requestRepo.Add(officeHour, models.RequestActivate)
|
||||||
Templates.ExecuteTemplate(w, "addSuccess.html", struct{}{})
|
b.serveTemplate(w, "addSuccess", nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,10 +164,5 @@ func (b *BaseHandler) writeAddOfficeHourMask(w http.ResponseWriter, req *http.Re
|
||||||
if len(data.Errors) != 0 {
|
if len(data.Errors) != 0 {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
err := Templates.ExecuteTemplate(w, "addMask.html", data)
|
b.serveTemplate(w, "addMask", data)
|
||||||
if err != nil {
|
|
||||||
log.Printf("Template addMask.html could not be parsed: %s", err.Error())
|
|
||||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", err.Error())))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,15 @@ func (b *BaseHandler) ConfirmRequestHandler(w http.ResponseWriter, req *http.Req
|
||||||
request, err := b.requestRepo.FindBySecret(secret)
|
request, err := b.requestRepo.FindBySecret(secret)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
b.serveTemplate(w, "requestNotFound", nil)
|
||||||
Templates.ExecuteTemplate(w, "requestNotFound.html", struct{}{})
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.requestRepo.Execute(request)
|
err = b.requestRepo.Execute(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
b.serveTemplate(w, "executeFailure", err.Error())
|
||||||
Templates.ExecuteTemplate(w, "executeFailure.html", err.Error())
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Templates.ExecuteTemplate(w, "executeSuccess.html", struct{}{})
|
b.serveTemplate(w, "executeSuccess", nil)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ func (b *BaseHandler) DeleteOfficeHourHandler(w http.ResponseWriter, req *http.R
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
}
|
}
|
||||||
_, err = b.requestRepo.Add(officeHour, models.RequestDelete)
|
_, err = b.requestRepo.Add(officeHour, models.RequestDelete)
|
||||||
Templates.ExecuteTemplate(w, "deleteSuccess.html", struct{}{})
|
b.serveTemplate(w, "deleteSuccess", nil)
|
||||||
} else {
|
} else {
|
||||||
officeHours, _ := b.officeHourRepo.GetAll(true)
|
officeHours, _ := b.officeHourRepo.GetAll(true)
|
||||||
timetable, slots := b.GetTimetable(officeHours)
|
timetable, slots := b.GetTimetable(officeHours)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"officeHours/models"
|
"officeHours/models"
|
||||||
|
@ -28,6 +27,7 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques
|
||||||
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.RootHandler(w, req)
|
b.RootHandler(w, req)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
course, err := b.courseRepo.FindById(courseid)
|
course, err := b.courseRepo.FindById(courseid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -51,9 +51,5 @@ func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Reques
|
||||||
SelectedRoom int
|
SelectedRoom int
|
||||||
SelectedCourse int
|
SelectedCourse int
|
||||||
}{courses, rooms, timetable, selectedRoom, selectedCourse}
|
}{courses, rooms, timetable, selectedRoom, selectedCourse}
|
||||||
err := Templates.ExecuteTemplate(w, "index.html", data)
|
b.serveTemplate(w, "index", data)
|
||||||
if err != nil {
|
|
||||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", err.Error())))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,47 @@
|
||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"net/http"
|
||||||
"officeHours/models"
|
"officeHours/models"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Templates, _ = template.Must(template.ParseFiles(
|
var funcs = template.FuncMap{
|
||||||
"templates/addFailure.html",
|
"DayName": models.DayName,
|
||||||
"templates/addMask.html",
|
"divide": func(i int, j int) int { return i / j },
|
||||||
"templates/addSuccess.html",
|
}
|
||||||
"templates/deleteSuccess.html",
|
var baseTemplate = template.Must(template.ParseFiles("templates/base.html")).New("base.html").Funcs(funcs)
|
||||||
"templates/executeFailure.html",
|
|
||||||
"templates/executeSuccess.html",
|
func (b *BaseHandler) serveTemplate(w http.ResponseWriter, name string, data any) {
|
||||||
"templates/footer.html",
|
full_name := "templates/" + name + ".html"
|
||||||
"templates/head.html",
|
// check that template exists
|
||||||
"templates/index.html",
|
info, err := os.Stat(full_name)
|
||||||
"templates/officeHourTable.html",
|
if (err != nil && os.IsNotExist(err)) || info.IsDir() {
|
||||||
"templates/requestNotFound.html")).
|
w.WriteHeader(http.StatusNotFound)
|
||||||
New("").Funcs(template.FuncMap{"DayName": models.DayName,
|
w.Write([]byte("404: Template nicht gefunden."))
|
||||||
"divide": func(i int, j int) int { return i / j }}).ParseFiles("templates/confirmationMail", "templates/td.html")
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
|
tmpl, err := baseTemplate.ParseFiles(full_name)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: log.Printf
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
johannes marked this conversation as resolved
Outdated
Gonne
commented
This could be an actual error using This could be an actual error using `fmt.Errorf`.
Furthermore I began logging in English. We should make that consistent.
|
|||||||
|
w.Write([]byte(fmt.Sprintf("500: Template "+full_name+" konnte nicht geparst werden : %s", err.Error())))
|
||||||
|
return
|
||||||
johannes marked this conversation as resolved
Outdated
Gonne
commented
I think, that StatusNotFound is for user supplied references (e.g. a course or a room id), but this should be an internal server error. I think, that StatusNotFound is for user supplied references (e.g. a course or a room id), but this should be an internal server error.
|
|||||||
|
}
|
||||||
|
// TODO: cache templates in parsed state, but not executed
|
||||||
|
err = template.Must(tmpl.Clone()).Execute(w, data)
|
||||||
|
if err != nil {
|
||||||
|
// TODO: log.Printf
|
||||||
Gonne
commented
Using this construction each template is parsed again and again, while it would be sufficient to parse them all on startup and later just execute them. Using this construction each template is parsed again and again, while it would be sufficient to parse them all on startup and later just execute them.
johannes
commented
Fixed (and spent too much time implementing this ^^) Fixed (and spent too much time implementing this ^^)
|
|||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(fmt.Sprintf("500: Template "+full_name+" konnte nicht ausgeführt werden : %s", err.Error())))
|
||||||
Gonne
commented
This could be an actual error using Furthermore error wrapping is something cool I just learnt. This could be an actual error using `fmt.Errorf`.
Furthermore I began logging in English. We should make that consistent.
Furthermore [error wrapping](https://blog.boot.dev/golang/wrapping-errors-in-go-how-to-handle-nested-errors/) is something cool I just learnt.
johannes
commented
Error wrapping looks nice. I started doing that. In general it seems best to wrap errors which occur during runtime from the beginning of a http request handler, which then logs the error and returns an error page to the user. (I added an inline TODO about that) Errors on startup however can just abort the whole program, like I implemented in Error wrapping looks nice. I started doing that.
In general it seems best to wrap errors which occur during runtime from the beginning of a http request handler, which then logs the error and returns an error page to the user. (I added an inline TODO about that)
Errors on startup however can just abort the whole program, like I implemented in `main.go`
|
|||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var RawTemplates = template.Must(template.New("").Funcs(funcs).ParseFiles(
|
||||||
|
"templates/confirmationMail",
|
||||||
|
"templates/td.html",
|
||||||
|
"templates/officeHourTable.html"))
|
||||||
|
|
|
@ -84,7 +84,7 @@ func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.Of
|
||||||
MinuteGranularity int
|
MinuteGranularity int
|
||||||
DeleteIcons bool
|
DeleteIcons bool
|
||||||
}{OfficeHour: current, MinuteGranularity: b.config.Date.MinuteGranularity, DeleteIcons: deleteIcons}
|
}{OfficeHour: current, MinuteGranularity: b.config.Date.MinuteGranularity, DeleteIcons: deleteIcons}
|
||||||
Templates.ExecuteTemplate(&celldata, "td.html", data)
|
RawTemplates.ExecuteTemplate(&celldata, "td.html", data)
|
||||||
tableBody += celldata.String()
|
tableBody += celldata.String()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -116,6 +116,6 @@ func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.Of
|
||||||
slots[4],
|
slots[4],
|
||||||
template.HTML(tableBody),
|
template.HTML(tableBody),
|
||||||
}
|
}
|
||||||
Templates.ExecuteTemplate(&table, "officeHourTable.html", tableData)
|
RawTemplates.ExecuteTemplate(&table, "officeHourTable.html", tableData)
|
||||||
return template.HTML(table.String())
|
return template.HTML(table.String())
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,7 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
Request models.Request
|
Request models.Request
|
||||||
}{r.config, request}
|
}{r.config, request}
|
||||||
err := controllers.Templates.ExecuteTemplate(&message, "confirmationMail", data)
|
err := controllers.RawTemplates.ExecuteTemplate(&message, "confirmationMail", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error parsing confirmation Mail: %s", err.Error())
|
log.Printf("Error parsing confirmation Mail: %s", err.Error())
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Fehler{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Sprechstunde anlegen</title>
|
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
||||||
{{template "head.html" .}}
|
<br />
|
||||||
</head>
|
{{.}}
|
||||||
<body>
|
{{end}}
|
||||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
|
||||||
<br />
|
|
||||||
{{.}}
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,50 +1,52 @@
|
||||||
<!DOCTYPE html>
|
<{{define "title"}}Sprechstunde anlegen{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Sprechstunde anlegen</title>
|
<p>
|
||||||
{{template "head.html" .}}
|
{{range .Errors}}{{.}}<br />{{end}}
|
||||||
</head>
|
</p>
|
||||||
<body>
|
<form method="POST" action="addOfficeHour">
|
||||||
<p>
|
<label for="veranstaltung">Veranstaltung</label>:
|
||||||
{{range .Errors}}{{.}}<br />{{end}}
|
<select name="veranstaltung" id="veranstaltung">
|
||||||
</p>
|
{{range $course := .Courses}}
|
||||||
<form method="POST" action="addOfficeHour">
|
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>
|
||||||
<label for="veranstaltung">Veranstaltung</label>:
|
{{end}}
|
||||||
<select name="veranstaltung" id="veranstaltung">{{range $course := .Courses}}
|
</select><br />
|
||||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
<label for="woche">Woche</label>:
|
||||||
</select><br />
|
<select name="woche" id="woche">
|
||||||
<label for="woche">Woche</label>:
|
<option value="0"{{if eq 0 $.Date.Week}} selected{{end}}>Jede</option>
|
||||||
<select name="woche" id="woche">
|
<option value="1"{{if eq 1 $.Date.Week}} selected{{end}}>Ungerade</option>
|
||||||
<option value="0"{{if eq 0 $.Date.Week}} selected{{end}}>Jede</option>
|
<option value="2"{{if eq 2 $.Date.Week}} selected{{end}}>Gerade</option>
|
||||||
<option value="1"{{if eq 1 $.Date.Week}} selected{{end}}>Ungerade</option>
|
</select><br />
|
||||||
<option value="2"{{if eq 2 $.Date.Week}} selected{{end}}>Gerade</option>
|
<label for="tag">Tag</label>: <select name="tag" id="tag">
|
||||||
</select><br />
|
<option value="0"{{if eq 0 $.Date.Day}} selected{{end}}>Montag</option>
|
||||||
<label for="tag">Tag</label>: <select name="tag" id="tag">
|
<option value="1"{{if eq 1 $.Date.Day}} selected{{end}}>Dienstag</option>
|
||||||
<option value="0"{{if eq 0 $.Date.Day}} selected{{end}}>Montag</option>
|
<option value="2"{{if eq 2 $.Date.Day}} selected{{end}}>Mittwoch</option>
|
||||||
<option value="1"{{if eq 1 $.Date.Day}} selected{{end}}>Dienstag</option>
|
<option value="3"{{if eq 3 $.Date.Day}} selected{{end}}>Donnerstag</option>
|
||||||
<option value="2"{{if eq 2 $.Date.Day}} selected{{end}}>Mittwoch</option>
|
<option value="4"{{if eq 4 $.Date.Day}} selected{{end}}>Freitag</option>
|
||||||
<option value="3"{{if eq 3 $.Date.Day}} selected{{end}}>Donnerstag</option>
|
</select><br />
|
||||||
<option value="4"{{if eq 4 $.Date.Day}} selected{{end}}>Freitag</option>
|
<label for="startzeit">Startzeit</label>: <input type="time" name="startzeit" id="startzeit" min="08:00" max="17:30" {{if gt $.Date.Hour 7}}value="{{printf "%02d" $.Date.Hour}}:{{printf "%02d" $.Date.Minute}}"{{end}} required/><br />
|
||||||
</select><br />
|
<label for="dauer">Dauer in Minuten</label>: <input name="dauer" id="dauer" type="number" min="{{.MinuteGranularity}}" max="120" step="{{.MinuteGranularity}}" value="{{.Duration}}" required/><br />
|
||||||
<label for="startzeit">Startzeit</label>: <input type="time" name="startzeit" id="startzeit" min="08:00" max="17:30" {{if gt $.Date.Hour 7}}value="{{printf "%02d" $.Date.Hour}}:{{printf "%02d" $.Date.Minute}}"{{end}} required/><br />
|
<label for="raum">Raum</label>:
|
||||||
<label for="dauer">Dauer in Minuten</label>: <input name="dauer" id="dauer" type="number" min="{{.MinuteGranularity}}" max="120" step="{{.MinuteGranularity}}" value="{{.Duration}}" required/><br />
|
<select name="raum" id="raum">
|
||||||
<label for="raum">Raum</label>:
|
{{range $room := .Rooms}}
|
||||||
<select name="raum" id="raum">{{range $room := .Rooms}}
|
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>
|
||||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
{{end}}
|
||||||
</select><br />
|
</select><br />
|
||||||
<label for="raumname">Raumname (für Sonderräume)</label>: <input type="text" name="raumname" id="raumname" value="{{.Roomname}}"/><br />
|
<label for="raumname">Raumname (für Sonderräume)</label>: <input type="text" name="raumname" id="raumname" value="{{.Roomname}}"/><br />
|
||||||
<label for="name">Name</label>: <input name="name" id="name" type="text" size="50" value="{{.Name}}" required/><br />
|
<label for="name">Name</label>: <input name="name" id="name" type="text" size="50" value="{{.Name}}" required/><br />
|
||||||
<label for="email">Email-Adresse</label>:
|
<label for="email">Email-Adresse</label>:
|
||||||
<input name="email" id="email" type="email" size="50" value="{{.Email}}" required/><br />
|
<input name="email" id="email" type="email" size="50" value="{{.Email}}" required/><br />
|
||||||
<label for="info">Info</label>: <input name="info" id="info" type="text" size="50" value="{{.Info}}"/><br />
|
<label for="info">Info</label>: <input name="info" id="info" type="text" size="50" value="{{.Info}}"/><br />
|
||||||
<input type="submit">
|
<input type="submit">
|
||||||
</form>
|
</form>
|
||||||
{{if ne .Config.Tutor.MailSuffix ""}}Du musst hier eine Email-Adresse angeben, die auf „{{.Config.Tutor.MailSuffix}}“ endet.<br />{{end}}
|
{{if ne .Config.Tutor.MailSuffix ""}}
|
||||||
Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich
|
Du musst hier eine Email-Adresse angeben, die auf „{{.Config.Tutor.MailSuffix}}“ endet.<br />
|
||||||
<dl>
|
{{end}}
|
||||||
{{range $room := .Rooms}}
|
Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich
|
||||||
<dt>{{$room.Name}}</dt><dd>{{$room.MaxOccupy}} Sprechstunde{{if gt $room.MaxOccupy 1}}n{{end}}</dd>{{end}}
|
<dl>
|
||||||
</dl>
|
{{range $room := .Rooms}}
|
||||||
{{template "footer.html" .}}
|
<dt>{{$room.Name}}</dt>
|
||||||
</body>
|
<dd>{{$room.MaxOccupy}} Sprechstunde{{if gt $room.MaxOccupy 1}}n{{end}}</dd>
|
||||||
</html>
|
{{end}}
|
||||||
|
</dl>
|
||||||
|
{{end}}
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Sprechstunde anlegen{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Sprechstunde anlegen</title>
|
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben.
|
||||||
{{template "head.html" .}}
|
{{end}}
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben.
|
|
||||||
<br />
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
27
templates/base.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="keywords" content="Mathebau, Sprechstunde, Sprechstunden, Mathe, Mathematik, technische, Universität, Darmstadt, TU, Fachschaft">
|
||||||
|
<meta name="description" content="Eine Übersicht der Sprechstunden, die in den offenen Arbeitsräumen der Fachschaft Mathematik, TU Darmstadt, angeboten werden">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
|
||||||
|
|
||||||
|
<title>{{block "title" .}}Start{{end}} – Sprechstunden</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
{{block "content" .}}Du solltest dies nicht sehen.{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer class="container">
|
||||||
|
<a href="/">Startseite</a><br />
|
||||||
|
<a href="/addOfficeHour">Sprechstunde anlegen</a><br />
|
||||||
|
<a href="/deleteOfficeHour">Sprechstunde löschen</a><br />
|
||||||
|
Technische Fragen an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="/static/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,13 +1,7 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Sprechstunde löschen{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Sprechstunde löschen</title>
|
Du solltest eine Mail mit einem Bestätigungslink erhalten haben. <br />
|
||||||
{{template "head.html" .}}
|
Sie wurde an die Adresse geschickt, mit der die Sprechstunde angelegt wurde.
|
||||||
</head>
|
<br />
|
||||||
<body>
|
{{end}}
|
||||||
Du solltest eine Mail mit einem Bestätigungslink erhalten haben. <br />
|
|
||||||
Sie wurde an die Adresse geschickt, mit der die Sprechstunde angelegt wurde.
|
|
||||||
<br />
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Anfrage ausführen fehlgeschlagen{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Anfrage ausführen fehlgeschlagen</title>
|
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
||||||
{{template "head.html" .}}
|
<br />
|
||||||
</head>
|
{{.}}
|
||||||
<body>
|
{{end}}
|
||||||
Irgendetwas ist schief gegangen. Bitte sende folgende Daten an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a> mit einer Beschreibung, was du tun wolltest.
|
|
||||||
<br />
|
|
||||||
{{.}}
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Anfrage ausgeführt{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Anfrage ausgeführt</title>
|
Deine Anfrage wurde ausgeführt.
|
||||||
{{template "head.html" .}}
|
{{end}}
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
Deine Anfrage wurde ausgeführt. <br />
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
<footer>
|
|
||||||
<a href="/">Startseite</a><br />
|
|
||||||
<a href="/addOfficeHour">Sprechstunde anlegen</a><br />
|
|
||||||
<a href="/deleteOfficeHour">Sprechstunde löschen</a><br />
|
|
||||||
Technische Fragen an <a href="mailto:sprechstundentool@mathebau.de">sprechstundentool@mathebau.de</a>
|
|
||||||
</footer>
|
|
|
@ -1,9 +0,0 @@
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="keywords" content="Mathebau, Sprechstunde, Sprechstunden, Mathe, Mathematik, technische, Universität, Darmstadt, TU, Fachschaft">
|
|
||||||
<meta name="description" content="Eine Übersicht der Sprechstunden, die in den offenen Arbeitsräumen der Fachschaft Mathematik, TU Darmstadt, angeboten werden">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
|
|
||||||
<!-- TODO: include this at the very bottom of <body> after refactoring to base template
|
|
||||||
<script src="/static/bootstrap/js/bootstrap.bundle.min.js"></script>
|
|
||||||
-->
|
|
|
@ -1,29 +1,25 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Übersicht{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Sprechstunden</title>
|
<form method="GET" action="/getByCourse">
|
||||||
{{template "head.html" .}}
|
<label for="veranstaltung">Veranstaltung: </label>
|
||||||
</head>
|
<select name="veranstaltung" id="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
||||||
<body>
|
<option value="">Alle</option>
|
||||||
<form method="GET" action="/getByCourse">
|
{{range $course := .Courses}}
|
||||||
<label for="veranstaltung">Veranstaltung: </label>
|
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>
|
||||||
<select name="veranstaltung" id="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
{{end}}
|
||||||
<option value="">Alle</option>
|
</select>
|
||||||
{{range $course := .Courses}}
|
<input type="submit" value="Auswählen" />
|
||||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
</form>
|
||||||
</select>
|
<form method="GET" action="/getByRoom">
|
||||||
<input type="submit" value="Auswählen" />
|
<label for="raum">Raum: </label>
|
||||||
</form>
|
<select name="raum" id="raum" size="1" onchange="document.forms[1].submit()">
|
||||||
<form method="GET" action="/getByRoom">
|
<option value="">Alle</option>
|
||||||
<label for="raum">Raum: </label>
|
{{range $room := .Rooms}}
|
||||||
<select name="raum" id="raum" size="1" onchange="document.forms[1].submit()">
|
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>
|
||||||
<option value="">Alle</option>
|
{{end}}
|
||||||
{{range $room := .Rooms}}
|
</select>
|
||||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
<input type="submit" value="Auswählen" />
|
||||||
</select>
|
</form>
|
||||||
<input type="submit" value="Auswählen" />
|
{{.Timetable}}
|
||||||
</form>
|
{{end}}
|
||||||
{{.Timetable}}
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
<!DOCTYPE html>
|
{{define "title"}}Anfrage bestätigen fehlgeschlagen{{end}}
|
||||||
<html lang="de">
|
|
||||||
<head>
|
{{define "content"}}
|
||||||
<title>Anfrage bestätigen fehlgeschlagen</title>
|
<p>
|
||||||
{{template "head.html" .}}
|
Dieser Bestätigungscode ist nicht verfügbar. <br />
|
||||||
</head>
|
Bitte gib deinen Bestätigungscode hier ein.
|
||||||
<body>
|
</p>
|
||||||
<p>
|
<form action="/confirmRequest">
|
||||||
Dieser Bestätigungscode ist nicht verfügbar. <br />
|
<label for="code">Bestätigungscode</label>: <input type="text" name="code" id="code"/>
|
||||||
Bitte gib deinen Bestätigungscode hier ein.
|
<input type="submit" />
|
||||||
</p>
|
</form>
|
||||||
<form action="/confirmRequest">
|
{{end}}
|
||||||
<label for="code">Bestätigungscode</label>: <input type="text" name="code" id="code"/>
|
|
||||||
<input type="submit" />
|
|
||||||
</form>
|
|
||||||
{{template "footer.html" .}}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
Here we should consider checking whether the name is restricted to something like
[a-zA-Z0-9]
to prevent directory traversal. Possibly it is sufficient to forbid/
and/or.
This is not longer relevant, since all available templates are listed in one place inside our code and we do not parse filenames from anywhere else.