rework template load/generation + add generic error on template error

This commit is contained in:
rmanach
2025-01-07 16:55:36 +01:00
parent 40e08154f6
commit 708db35214
13 changed files with 501 additions and 449 deletions
+7 -1
View File
@@ -28,6 +28,12 @@
.error {
color: red;
}
.col-item {
margin: 10px;
word-wrap: break-word;
width: 200px;
}
</style>
</head>
@@ -54,7 +60,7 @@
</body>
<script type="text/javascript">
{{ block "script" . }}{{ end }}
{{ block "script". }} {{ end }}
</script>
</html>
+4
View File
@@ -0,0 +1,4 @@
{{ define "content" }}
<h1>Error</h1>
<div>Unexpected error occurred, try again or contact the support.</div>
{{ end }}
+23 -6
View File
@@ -24,6 +24,7 @@
{{ if ne (errStr .Error) "" }}
<div class="error">{{.Error | errStr}}</div>
{{ end }}
{{ if .Results }}
<table>
<tr>
<th>Name</th>
@@ -34,15 +35,31 @@
</tr>
{{range .Results}}
<tr>
<td><div style="margin: 10px; word-wrap: break-word; width: 300px;">{{.Name}}</div></td>
<td><div style="margin: 10px; word-wrap: break-word; width: 300px;">{{.Description | noDesc}}</div></td>
<td style="text-align: center;"><div style="margin: 10px;">{{.Editor}}</div></td>
<td style="text-align: center; word-wrap: break-word; width: 300px;"><div style="margin: 10px;">{{.Authors | join }}</div></td>
<td><div style="margin: 20px;">{{.Year}}</div></td>
<td><div style="margin: 20px;"><a target="_blank" href="{{.Path | bookUrl}}">Download</a></div></td>
<td>
<div class="col-item">{{.Name}}</div>
</td>
<td>
<div class="col-item">{{.Description | noDesc}}</div>
</td>
<td style="text-align: center;">
<div class="col-item">{{.Editor}}</div>
</td>
<td style="text-align: center">
<div class="col-item">{{.Authors | join }}</div>
</td>
<td style="text-align: center">
<div class="col-item">{{.Year}}</div>
</td>
<td style="text-align: center">
<div class="col-item">
<a target="_blank" href="{{.GetPath | bookUrl}}">Download</a>
</div>
</td>
</tr>
{{ end }}
</table>
<div>{{len .Results}} results found</div>
{{ end }}
</ul>
{{ end }}
+92 -51
View File
@@ -1,32 +1,46 @@
package templates
import (
"bytes"
_ "embed"
"fmt"
"html/template"
"mime/multipart"
"net/http"
"path/filepath"
"strconv"
"strings"
"sync"
"github.com/rs/zerolog/log"
"librapi/handlers/download"
)
//go:embed base.html.tpl
var base string
var (
//go:embed base.html.tpl
base string
//go:embed login/login_form.html.tpl
var loginForm string
//go:embed login/login_form.html.tpl
loginForm string
//go:embed login/login_success.html.tpl
var loginSuccess string
//go:embed login/login_success.html.tpl
loginSuccess string
//go:embed upload_form.html.tpl
var uploadForm string
//go:embed upload_form.html.tpl
uploadForm string
//go:embed home.html.tpl
var home string
//go:embed home.html.tpl
home string
//go:embed error.html.tpl
errorBase string
loginFormTmpl = loadLoginFormTmpl()
loginSuccessTmpl = loadLoginSuccessTmpl()
errTmpl = loadErrorTmpl()
homeTmpl = loadHomeTmpl()
uploadFormTmpl = loadUploadFormTmpl()
)
var funcMap = template.FuncMap{
"year": func(s int) string {
@@ -56,7 +70,7 @@ var funcMap = template.FuncMap{
},
"bookUrl": func(path string) string {
_, filename := filepath.Split(path)
return fmt.Sprintf("/download?file=%s", filename)
return fmt.Sprintf("%s?file=%s", download.URL, filename)
},
"noDesc": func(desc *string) string {
if desc == nil {
@@ -66,46 +80,20 @@ var funcMap = template.FuncMap{
},
}
var homeTmpl = sync.OnceValue[*template.Template](func() *template.Template {
func loadErrorTmpl() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("home").Funcs(funcMap).Parse(home); err != nil {
log.Fatal().Err(err).Msg("unable to parse home tmpl")
if _, err := baseTmpl.New("error").Funcs(funcMap).Parse(errorBase); err != nil {
log.Fatal().Err(err).Msg("unable to parse error base tmpl")
}
return baseTmpl
})
}
var uploadFormTmpl = sync.OnceValue[*template.Template](func() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("uploadForm").Funcs(funcMap).Parse(uploadForm); err != nil {
log.Fatal().Err(err).Msg("unable to parse upload tmpl")
}
return baseTmpl
})
var loginFormTmpl = sync.OnceValue[*template.Template](func() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("loginForm").Funcs(funcMap).Parse(loginForm); err != nil {
log.Fatal().Err(err).Msg("unable to parse login tmpl")
}
return baseTmpl
})
var loginSuccessTmpl = sync.OnceValue[*template.Template](func() *template.Template {
func loadLoginSuccessTmpl() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
@@ -116,20 +104,73 @@ var loginSuccessTmpl = sync.OnceValue[*template.Template](func() *template.Templ
}
return baseTmpl
})
}
func loadLoginFormTmpl() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("loginForm").Funcs(funcMap).Parse(loginForm); err != nil {
log.Fatal().Err(err).Msg("unable to parse login form tmpl")
}
return baseTmpl
}
func loadHomeTmpl() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("home").Funcs(funcMap).Parse(home); err != nil {
log.Fatal().Err(err).Msg("unable to parse home tmpl")
}
return baseTmpl
}
func loadUploadFormTmpl() *template.Template {
baseTmpl, err := template.New("base").Parse(base)
if err != nil {
log.Fatal().Err(err).Msg("unable to parse base tmpl")
}
if _, err := baseTmpl.New("uploadform").Funcs(funcMap).Parse(uploadForm); err != nil {
log.Fatal().Err(err).Msg("unable to parse upload form tmpl")
}
return baseTmpl
}
func GetHome() *template.Template {
return homeTmpl()
return homeTmpl
}
func GetLoginForm() *template.Template {
return loginFormTmpl()
func executeTmpl(tmpl *template.Template, form any, w http.ResponseWriter) (string, error) {
buf := bytes.NewBufferString("")
if err := tmpl.Execute(buf, form); err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w, errTmpl)
return "", err
}
return buf.String(), nil
}
func GetLoginSuccess() *template.Template {
return loginSuccessTmpl()
func ExecuteLoginSuccessTmpl(w http.ResponseWriter) (string, error) {
return executeTmpl(loginSuccessTmpl, nil, w)
}
func GetUploadForm() *template.Template {
return uploadFormTmpl()
func ExecuteLoginFormTmpl(form any, w http.ResponseWriter) (string, error) {
return executeTmpl(loginFormTmpl, form, w)
}
func ExecuteHomeTmpl(form any, w http.ResponseWriter) (string, error) {
return executeTmpl(homeTmpl, form, w)
}
func ExecuteUploadFormTmpl(form any, w http.ResponseWriter) (string, error) {
return executeTmpl(uploadFormTmpl, form, w)
}