preparations for styling: refactor template rendering #1
|
@ -2,7 +2,6 @@ package controllers
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
"officeHours/config"
|
||||
|
@ -149,12 +148,12 @@ func (b *BaseHandler) AddOfficeHourHandler(w http.ResponseWriter, req *http.Requ
|
|||
id, err := b.officeHourRepo.Add(officeHour)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Templates.ExecuteTemplate(w, "addFailure.html", err)
|
||||
b.serveTemplate(w, "addFailure", err)
|
||||
return
|
||||
}
|
||||
officeHour, _ = b.officeHourRepo.FindById(id)
|
||||
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 {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
err := Templates.ExecuteTemplate(w, "addMask.html", 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
|
||||
}
|
||||
b.serveTemplate(w, "addMask", data)
|
||||
}
|
||||
|
|
|
@ -9,17 +9,15 @@ func (b *BaseHandler) ConfirmRequestHandler(w http.ResponseWriter, req *http.Req
|
|||
request, err := b.requestRepo.FindBySecret(secret)
|
||||
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
Templates.ExecuteTemplate(w, "requestNotFound.html", struct{}{})
|
||||
b.serveTemplate(w, "requestNotFound", nil)
|
||||
return
|
||||
}
|
||||
|
||||
err = b.requestRepo.Execute(request)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
Templates.ExecuteTemplate(w, "executeFailure.html", err.Error())
|
||||
b.serveTemplate(w, "executeFailure", err.Error())
|
||||
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)
|
||||
}
|
||||
_, err = b.requestRepo.Add(officeHour, models.RequestDelete)
|
||||
Templates.ExecuteTemplate(w, "deleteSuccess.html", struct{}{})
|
||||
b.serveTemplate(w, "deleteSuccess", nil)
|
||||
} else {
|
||||
officeHours, _ := b.officeHourRepo.GetAll(true)
|
||||
timetable, slots := b.GetTimetable(officeHours)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"officeHours/models"
|
||||
|
@ -28,6 +27,7 @@ func (b *BaseHandler) GetByCourseHandler(w http.ResponseWriter, req *http.Reques
|
|||
courseid, err := strconv.Atoi(req.FormValue("veranstaltung"))
|
||||
if err != nil {
|
||||
b.RootHandler(w, req)
|
||||
return
|
||||
}
|
||||
course, err := b.courseRepo.FindById(courseid)
|
||||
if err != nil {
|
||||
|
@ -51,9 +51,5 @@ func (b *BaseHandler) writeTimetablePage(w http.ResponseWriter, req *http.Reques
|
|||
SelectedRoom int
|
||||
SelectedCourse int
|
||||
}{courses, rooms, timetable, selectedRoom, selectedCourse}
|
||||
err := Templates.ExecuteTemplate(w, "index.html", data)
|
||||
if err != nil {
|
||||
w.Write([]byte(fmt.Sprintf("Template konnte nicht geparst werden : %s", err.Error())))
|
||||
return
|
||||
}
|
||||
b.serveTemplate(w, "index", data)
|
||||
}
|
||||
|
|
|
@ -1,21 +1,47 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"officeHours/models"
|
||||
"os"
|
||||
)
|
||||
|
||||
var Templates, _ = template.Must(template.ParseFiles(
|
||||
"templates/addFailure.html",
|
||||
"templates/addMask.html",
|
||||
"templates/addSuccess.html",
|
||||
"templates/deleteSuccess.html",
|
||||
"templates/executeFailure.html",
|
||||
"templates/executeSuccess.html",
|
||||
"templates/footer.html",
|
||||
"templates/head.html",
|
||||
"templates/index.html",
|
||||
"templates/officeHourTable.html",
|
||||
"templates/requestNotFound.html")).
|
||||
New("").Funcs(template.FuncMap{"DayName": models.DayName,
|
||||
"divide": func(i int, j int) int { return i / j }}).ParseFiles("templates/confirmationMail", "templates/td.html")
|
||||
var funcs = template.FuncMap{
|
||||
"DayName": models.DayName,
|
||||
"divide": func(i int, j int) int { return i / j },
|
||||
}
|
||||
var baseTemplate = template.Must(template.ParseFiles("templates/base.html")).New("base.html").Funcs(funcs)
|
||||
|
||||
func (b *BaseHandler) serveTemplate(w http.ResponseWriter, name string, data any) {
|
||||
full_name := "templates/" + name + ".html"
|
||||
// check that template exists
|
||||
info, err := os.Stat(full_name)
|
||||
if (err != nil && os.IsNotExist(err)) || info.IsDir() {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("404: Template nicht gefunden."))
|
||||
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
|
||||
DeleteIcons bool
|
||||
}{OfficeHour: current, MinuteGranularity: b.config.Date.MinuteGranularity, DeleteIcons: deleteIcons}
|
||||
Templates.ExecuteTemplate(&celldata, "td.html", data)
|
||||
RawTemplates.ExecuteTemplate(&celldata, "td.html", data)
|
||||
tableBody += celldata.String()
|
||||
}
|
||||
} else {
|
||||
|
@ -116,6 +116,6 @@ func (b *BaseHandler) printTimetable(timetable map[models.Date]map[int]models.Of
|
|||
slots[4],
|
||||
template.HTML(tableBody),
|
||||
}
|
||||
Templates.ExecuteTemplate(&table, "officeHourTable.html", tableData)
|
||||
RawTemplates.ExecuteTemplate(&table, "officeHourTable.html", tableData)
|
||||
return template.HTML(table.String())
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ func (r *RequestRepo) sendConfirmationMail(request models.Request) error {
|
|||
Config config.Config
|
||||
Request models.Request
|
||||
}{r.config, request}
|
||||
err := controllers.Templates.ExecuteTemplate(&message, "confirmationMail", data)
|
||||
err := controllers.RawTemplates.ExecuteTemplate(&message, "confirmationMail", data)
|
||||
if err != nil {
|
||||
log.Printf("Error parsing confirmation Mail: %s", err.Error())
|
||||
return err
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Sprechstunde anlegen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
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>
|
||||
{{define "title"}}Fehler{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
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 />
|
||||
{{.}}
|
||||
{{end}}
|
||||
|
|
|
@ -1,50 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Sprechstunde anlegen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
{{range .Errors}}{{.}}<br />{{end}}
|
||||
</p>
|
||||
<form method="POST" action="addOfficeHour">
|
||||
<label for="veranstaltung">Veranstaltung</label>:
|
||||
<select name="veranstaltung" id="veranstaltung">{{range $course := .Courses}}
|
||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
||||
</select><br />
|
||||
<label for="woche">Woche</label>:
|
||||
<select name="woche" id="woche">
|
||||
<option value="0"{{if eq 0 $.Date.Week}} selected{{end}}>Jede</option>
|
||||
<option value="1"{{if eq 1 $.Date.Week}} selected{{end}}>Ungerade</option>
|
||||
<option value="2"{{if eq 2 $.Date.Week}} selected{{end}}>Gerade</option>
|
||||
</select><br />
|
||||
<label for="tag">Tag</label>: <select name="tag" id="tag">
|
||||
<option value="0"{{if eq 0 $.Date.Day}} selected{{end}}>Montag</option>
|
||||
<option value="1"{{if eq 1 $.Date.Day}} selected{{end}}>Dienstag</option>
|
||||
<option value="2"{{if eq 2 $.Date.Day}} selected{{end}}>Mittwoch</option>
|
||||
<option value="3"{{if eq 3 $.Date.Day}} selected{{end}}>Donnerstag</option>
|
||||
<option value="4"{{if eq 4 $.Date.Day}} selected{{end}}>Freitag</option>
|
||||
</select><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="dauer">Dauer in Minuten</label>: <input name="dauer" id="dauer" type="number" min="{{.MinuteGranularity}}" max="120" step="{{.MinuteGranularity}}" value="{{.Duration}}" required/><br />
|
||||
<label for="raum">Raum</label>:
|
||||
<select name="raum" id="raum">{{range $room := .Rooms}}
|
||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
||||
</select><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="email">Email-Adresse</label>:
|
||||
<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 />
|
||||
<input type="submit">
|
||||
</form>
|
||||
{{if ne .Config.Tutor.MailSuffix ""}}Du musst hier eine Email-Adresse angeben, die auf „{{.Config.Tutor.MailSuffix}}“ endet.<br />{{end}}
|
||||
Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich
|
||||
<dl>
|
||||
{{range $room := .Rooms}}
|
||||
<dt>{{$room.Name}}</dt><dd>{{$room.MaxOccupy}} Sprechstunde{{if gt $room.MaxOccupy 1}}n{{end}}</dd>{{end}}
|
||||
</dl>
|
||||
{{template "footer.html" .}}
|
||||
</body>
|
||||
</html>
|
||||
<{{define "title"}}Sprechstunde anlegen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<p>
|
||||
{{range .Errors}}{{.}}<br />{{end}}
|
||||
</p>
|
||||
<form method="POST" action="addOfficeHour">
|
||||
<label for="veranstaltung">Veranstaltung</label>:
|
||||
<select name="veranstaltung" id="veranstaltung">
|
||||
{{range $course := .Courses}}
|
||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>
|
||||
{{end}}
|
||||
</select><br />
|
||||
<label for="woche">Woche</label>:
|
||||
<select name="woche" id="woche">
|
||||
<option value="0"{{if eq 0 $.Date.Week}} selected{{end}}>Jede</option>
|
||||
<option value="1"{{if eq 1 $.Date.Week}} selected{{end}}>Ungerade</option>
|
||||
<option value="2"{{if eq 2 $.Date.Week}} selected{{end}}>Gerade</option>
|
||||
</select><br />
|
||||
<label for="tag">Tag</label>: <select name="tag" id="tag">
|
||||
<option value="0"{{if eq 0 $.Date.Day}} selected{{end}}>Montag</option>
|
||||
<option value="1"{{if eq 1 $.Date.Day}} selected{{end}}>Dienstag</option>
|
||||
<option value="2"{{if eq 2 $.Date.Day}} selected{{end}}>Mittwoch</option>
|
||||
<option value="3"{{if eq 3 $.Date.Day}} selected{{end}}>Donnerstag</option>
|
||||
<option value="4"{{if eq 4 $.Date.Day}} selected{{end}}>Freitag</option>
|
||||
</select><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="dauer">Dauer in Minuten</label>: <input name="dauer" id="dauer" type="number" min="{{.MinuteGranularity}}" max="120" step="{{.MinuteGranularity}}" value="{{.Duration}}" required/><br />
|
||||
<label for="raum">Raum</label>:
|
||||
<select name="raum" id="raum">
|
||||
{{range $room := .Rooms}}
|
||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>
|
||||
{{end}}
|
||||
</select><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="email">Email-Adresse</label>:
|
||||
<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 />
|
||||
<input type="submit">
|
||||
</form>
|
||||
{{if ne .Config.Tutor.MailSuffix ""}}
|
||||
Du musst hier eine Email-Adresse angeben, die auf „{{.Config.Tutor.MailSuffix}}“ endet.<br />
|
||||
{{end}}
|
||||
Außerdem dürfen in Räumen nur begrenzt viele Sprechstunden gleichzeitig stattfinden, nämlich
|
||||
<dl>
|
||||
{{range $room := .Rooms}}
|
||||
<dt>{{$room.Name}}</dt>
|
||||
<dd>{{$room.MaxOccupy}} Sprechstunde{{if gt $room.MaxOccupy 1}}n{{end}}</dd>
|
||||
{{end}}
|
||||
</dl>
|
||||
{{end}}
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Sprechstunde anlegen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben.
|
||||
<br />
|
||||
{{template "footer.html" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}Sprechstunde anlegen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
Die Sprechstunde wurde angelegt. Du solltest eine Mail mit einem Aktivierungslink erhalten haben.
|
||||
{{end}}
|
||||
|
|
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>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Sprechstunde löschen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
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>
|
||||
{{define "title"}}Sprechstunde löschen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
Du solltest eine Mail mit einem Bestätigungslink erhalten haben. <br />
|
||||
Sie wurde an die Adresse geschickt, mit der die Sprechstunde angelegt wurde.
|
||||
<br />
|
||||
{{end}}
|
||||
|
|
|
@ -1,13 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Anfrage ausführen fehlgeschlagen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
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>
|
||||
{{define "title"}}Anfrage ausführen fehlgeschlagen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
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 />
|
||||
{{.}}
|
||||
{{end}}
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Anfrage ausgeführt</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
Deine Anfrage wurde ausgeführt. <br />
|
||||
{{template "footer.html" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}Anfrage ausgeführt{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
Deine Anfrage wurde ausgeführt.
|
||||
{{end}}
|
||||
|
|
|
@ -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>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Sprechstunden</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
<form method="GET" action="/getByCourse">
|
||||
<label for="veranstaltung">Veranstaltung: </label>
|
||||
<select name="veranstaltung" id="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
||||
<option value="">Alle</option>
|
||||
{{range $course := .Courses}}
|
||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>{{end}}
|
||||
</select>
|
||||
<input type="submit" value="Auswählen" />
|
||||
</form>
|
||||
<form method="GET" action="/getByRoom">
|
||||
<label for="raum">Raum: </label>
|
||||
<select name="raum" id="raum" size="1" onchange="document.forms[1].submit()">
|
||||
<option value="">Alle</option>
|
||||
{{range $room := .Rooms}}
|
||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>{{end}}
|
||||
</select>
|
||||
<input type="submit" value="Auswählen" />
|
||||
</form>
|
||||
{{.Timetable}}
|
||||
{{template "footer.html" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}Übersicht{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<form method="GET" action="/getByCourse">
|
||||
<label for="veranstaltung">Veranstaltung: </label>
|
||||
<select name="veranstaltung" id="veranstaltung" size="1" onchange="document.forms[0].submit()">
|
||||
<option value="">Alle</option>
|
||||
{{range $course := .Courses}}
|
||||
<option value="{{$course.Id}}"{{if eq $course.Id $.SelectedCourse}} selected{{end}}>{{$course.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<input type="submit" value="Auswählen" />
|
||||
</form>
|
||||
<form method="GET" action="/getByRoom">
|
||||
<label for="raum">Raum: </label>
|
||||
<select name="raum" id="raum" size="1" onchange="document.forms[1].submit()">
|
||||
<option value="">Alle</option>
|
||||
{{range $room := .Rooms}}
|
||||
<option value="{{$room.Id}}"{{if eq $room.Id $.SelectedRoom}} selected{{end}}>{{$room.Name}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
<input type="submit" value="Auswählen" />
|
||||
</form>
|
||||
{{.Timetable}}
|
||||
{{end}}
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<title>Anfrage bestätigen fehlgeschlagen</title>
|
||||
{{template "head.html" .}}
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Dieser Bestätigungscode ist nicht verfügbar. <br />
|
||||
Bitte gib deinen Bestätigungscode hier ein.
|
||||
</p>
|
||||
<form action="/confirmRequest">
|
||||
<label for="code">Bestätigungscode</label>: <input type="text" name="code" id="code"/>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
{{template "footer.html" .}}
|
||||
</body>
|
||||
</html>
|
||||
{{define "title"}}Anfrage bestätigen fehlgeschlagen{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<p>
|
||||
Dieser Bestätigungscode ist nicht verfügbar. <br />
|
||||
Bitte gib deinen Bestätigungscode hier ein.
|
||||
</p>
|
||||
<form action="/confirmRequest">
|
||||
<label for="code">Bestätigungscode</label>: <input type="text" name="code" id="code"/>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
{{end}}
|
||||
|
|
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.