diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2fdc5c2 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright © 2024 NAME HERE + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/err_404.go b/err_404.go new file mode 100644 index 0000000..f12f7a0 --- /dev/null +++ b/err_404.go @@ -0,0 +1,17 @@ +package templates + +import ( + "fmt" + "net/http" +) + +func (T Templates) Err404(w http.ResponseWriter, r *http.Request) { + fmt.Println("404: " + r.URL.Path) + e := T.internalNewSplain( + "File Not Found", + "Couldn't find that. Maybe it's us?", + "Let us know if it happens a lot.", + 404, + ) + T.internalTemplateErrorSplash(w, r, e) +} diff --git a/errsplain.go b/errsplain.go new file mode 100644 index 0000000..51cfadd --- /dev/null +++ b/errsplain.go @@ -0,0 +1,17 @@ +package templates + +type ErrorSplain struct { + Title string + Explanation string + Remediation string + Status int +} + +func (T Templates) internalNewSplain(title string, explanation string, remediation string, status int) ErrorSplain { + return ErrorSplain{ + Title: title, + Explanation: explanation, + Remediation: remediation, + Status: status, + } +} diff --git a/example_templates/base.html b/example_templates/base.html new file mode 100644 index 0000000..e37ff61 --- /dev/null +++ b/example_templates/base.html @@ -0,0 +1,19 @@ +{{define "base"}} + + + + + + {{.Title}} + + + +
+ {{ template "nav.html" .}} +
+

{{.Title}}

+
+ {{ template "content" .}} +
+ + diff --git a/example_templates/error.html b/example_templates/error.html new file mode 100644 index 0000000..36ee0e7 --- /dev/null +++ b/example_templates/error.html @@ -0,0 +1,8 @@ +{{template "base" .}} +{{define "content" }} +

It seems we encountered a problem...

+

{{.Title}}

+

{{.Explanation}}

+

Possible Resolution:

+

{{.Remediation}}

+{{end}} \ No newline at end of file diff --git a/example_templates/home.html b/example_templates/home.html new file mode 100644 index 0000000..6230cce --- /dev/null +++ b/example_templates/home.html @@ -0,0 +1,4 @@ +{{template "base" .}} +{{define "content" }} +

Hello world

+{{end}} \ No newline at end of file diff --git a/example_templates/nav.html b/example_templates/nav.html new file mode 100644 index 0000000..031949c --- /dev/null +++ b/example_templates/nav.html @@ -0,0 +1,17 @@ + diff --git a/example_test.go b/example_test.go new file mode 100644 index 0000000..1063010 --- /dev/null +++ b/example_test.go @@ -0,0 +1,29 @@ +package templates_test + +import ( + "embed" + "fmt" + "io" + "net/http" + "net/http/httptest" + + "git.bivouac.wiki/use/templates" +) + +//go:embed example_templates +var tpfs embed.FS + +func ExampleTemplates() { + a := templates.NewTemplates(tpfs, "example_templates", "base.html", "nav.html") + v := struct{}{} + r := httptest.NewRequest(http.MethodGet, "home.html", nil) + w := httptest.NewRecorder() + a.TemplateEnd("home.html", w, r, v) + res := w.Result() + defer res.Body.Close() + data, err := io.ReadAll(res.Body) + if err != nil { + fmt.Errorf("expected error to be nil got %v", err) + } + fmt.Println(string(data)) +} diff --git a/init.go b/init.go new file mode 100644 index 0000000..a9cf03f --- /dev/null +++ b/init.go @@ -0,0 +1,28 @@ +package templates + +import ( + "embed" + "html/template" +) + +type Templates map[string]*template.Template + +// NewTemplates creates a new responder (embedded_dir should have a trailing slash) +func NewTemplates(given_fs embed.FS, embedded_dir string, variadics ...string) Templates { + // todo later: allow both io/fs.FS and embed.FS as called arguments + templates := make(map[string]*template.Template) + pages, _ := given_fs.ReadDir(embedded_dir) + for _, page := range pages { + file_path := embedded_dir + page.Name() + files := []string{file_path} + for _, v := range variadics { + files = append(files, embedded_dir+v) // add prefix + } + // files = append(files, variadics...) + tpl := template.Must( + template.New(page.Name()).ParseFS(given_fs, files...)) //+".html")) + templates[page.Name()] = tpl + // fmt.Println(page.Name()) + } + return templates +} diff --git a/internal_error_splash.go b/internal_error_splash.go new file mode 100644 index 0000000..167ae0f --- /dev/null +++ b/internal_error_splash.go @@ -0,0 +1,30 @@ +package templates + +import ( + "fmt" + "net/http" +) + +func (T Templates) internalTemplateErrorSplash(w http.ResponseWriter, r *http.Request, e ErrorSplain) { + w.Header().Set("Content-Type", "text/html") + w.WriteHeader(e.Status) + // w.WriteHeader(http.StatusInternalServerError) + type v struct { + Title string + LoggedIn bool + Explanation string + Remediation string + } + s := v{ + Title: "error", + LoggedIn: false, + Explanation: e.Explanation, + Remediation: e.Remediation, + } + err := T["error.html"].ExecuteTemplate(w, "error.html", s) + if err != nil { + fmt.Println(err) + } + return + +} diff --git a/middleware.go b/middleware.go deleted file mode 100644 index dac8432..0000000 --- a/middleware.go +++ /dev/null @@ -1 +0,0 @@ -package templates diff --git a/new_repl.go b/new_repl.go new file mode 100644 index 0000000..3454be3 --- /dev/null +++ b/new_repl.go @@ -0,0 +1,17 @@ +package templates + +import ( + "fmt" + "net/http" +) + +func (T Templates) NewRepl(err error, w http.ResponseWriter, r *http.Request, title string, explanation string, remediation string) { + e := T.internalNewSplain( + title, + explanation, + remediation, + 500, + ) + T.internalTemplateErrorSplash(w, r, e) + fmt.Println(err) +} diff --git a/template_end.go b/template_end.go new file mode 100644 index 0000000..a3ae187 --- /dev/null +++ b/template_end.go @@ -0,0 +1,11 @@ +package templates + +import "net/http" + +func (T Templates) TemplateEnd(template_name string, w http.ResponseWriter, r *http.Request, v any) { + w.Header().Set("Content-Type", "text/html") + err := T[template_name].ExecuteTemplate(w, template_name, v) + if err != nil { + T.ReplTemplateIssue(err, w, r) + } +} diff --git a/template_issue.go b/template_issue.go new file mode 100644 index 0000000..82e84f7 --- /dev/null +++ b/template_issue.go @@ -0,0 +1,17 @@ +package templates + +import ( + "net/http" + "time" +) + +func (T Templates) ReplTemplateIssue(err error, w http.ResponseWriter, r *http.Request) { + T.NewRepl( + err, + w, + r, + "Template problem", + "Something's wrong with our templates.", + "email us this timestamp: "+time.Now().String(), + ) +}