From b2447bc967df37b31282a97e32c581954bb8bcc9 Mon Sep 17 00:00:00 2001 From: René 'Necoro' Neumann Date: Thu, 17 Oct 2024 16:37:23 +0200 Subject: Move from html/template to templ --- csrf/csrf.go | 17 ++-- form/builder.go | 96 ------------------ form/errors.go | 30 ++++++ form/field.templ | 42 ++++++++ form/field_templ.go | 239 +++++++++++++++++++++++++++++++++++++++++++++ form/form.go | 21 ++++ form/reflect.go | 12 +-- go.mod | 1 + go.sum | 8 +- pages/base.templ | 77 +++++++++++++++ pages/base_templ.go | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++ pages/login.go | 10 +- pages/login.templ | 18 ++++ pages/login_templ.go | 74 ++++++++++++++ pages/page.go | 58 ++++++----- pages/pages.go | 8 +- pages/pages.templ | 46 +++++++++ pages/pages_templ.go | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++ templ/404.tpl | 10 -- templ/base.tpl | 20 ---- templ/categories.tpl | 9 -- templ/content.tpl | 36 ------- templ/form.tpl | 22 ----- templ/index.tpl | 3 - templ/login.tpl | 10 -- templ/navlinks.tpl | 8 -- templ/recur.tpl | 9 -- templ/template.go | 73 -------------- 28 files changed, 1144 insertions(+), 346 deletions(-) delete mode 100644 form/builder.go create mode 100644 form/errors.go create mode 100644 form/field.templ create mode 100644 form/field_templ.go create mode 100644 form/form.go create mode 100644 pages/base.templ create mode 100644 pages/base_templ.go create mode 100644 pages/login.templ create mode 100644 pages/login_templ.go create mode 100644 pages/pages.templ create mode 100644 pages/pages_templ.go delete mode 100644 templ/404.tpl delete mode 100644 templ/base.tpl delete mode 100644 templ/categories.tpl delete mode 100644 templ/content.tpl delete mode 100644 templ/form.tpl delete mode 100644 templ/index.tpl delete mode 100644 templ/login.tpl delete mode 100644 templ/navlinks.tpl delete mode 100644 templ/recur.tpl delete mode 100644 templ/template.go diff --git a/csrf/csrf.go b/csrf/csrf.go index 18fdb81..fd73c0d 100644 --- a/csrf/csrf.go +++ b/csrf/csrf.go @@ -4,6 +4,7 @@ import ( "html/template" "net/http" + "github.com/a-h/templ" "github.com/gorilla/csrf" "github.com/gorilla/securecookie" ) @@ -12,18 +13,22 @@ func Handler() func(http.Handler) http.Handler { return csrf.Protect( securecookie.GenerateRandomKey(32), csrf.SameSite(csrf.SameSiteStrictMode), - csrf.FieldName("csrf.csrffield"), // should match the structure in `Csrf` + csrf.FieldName("csrffield.field"), // should match the structure in `Csrf` ) } -// Csrf handles the CSRF data for a form. +// CsrfField handles the CSRF data for a form. // Include it verbatim and then use `{{.CsrfField}}` in templates. -type Csrf struct { - CsrfField template.HTML `form:"-" schema:"-"` +type CsrfField struct { + field template.HTML `form:"-" schema:"-"` } -func (c *Csrf) SetCsrfField(r *http.Request) { - c.CsrfField = csrf.TemplateField(r) +func (c *CsrfField) SetCsrfField(r *http.Request) { + c.field = csrf.TemplateField(r) +} + +func (c *CsrfField) Csrf() templ.Component { + return templ.Raw(c.field) } type Enabled interface { diff --git a/form/builder.go b/form/builder.go deleted file mode 100644 index 97e972f..0000000 --- a/form/builder.go +++ /dev/null @@ -1,96 +0,0 @@ -package form - -import ( - "errors" - "fmt" - "html/template" - "strings" -) - -type builder struct { - tpl *template.Template -} - -// Inputs will parse the provided struct into fields and then execute the -// template with each field. The returned HTML is simply all of these results -// appended one after another. -// -// Inputs' second argument - errs - will be used to render errors for -// individual fields. -func (b *builder) Inputs(v interface{}, errs ...error) (template.HTML, error) { - tpl, err := b.tpl.Clone() - if err != nil { - return "", err - } - fields := fields(v) - errors := fieldErrors(errs) - var html template.HTML - for _, field := range fields { - var sb strings.Builder - tpl.Funcs(template.FuncMap{ - "errors": func() []string { - if errs, ok := errors[field.Name]; ok { - return errs - } - return nil - }, - }) - err := tpl.Execute(&sb, field) - if err != nil { - return "", err - } - html = html + template.HTML(sb.String()) - } - return html, nil -} - -// FuncMap returns a template.FuncMap that defines both the inputs_for and -// inputs_and_errors_for functions for usage in the template package. The -// latter is provided via a closure because variadic parameters and the -// template package don't play very nicely and this just simplifies things -// a lot for end users of the form package. -func FuncMap(formTpl *template.Template) template.FuncMap { - b := builder{tpl: formTpl} - return template.FuncMap{ - "inputs_for": b.Inputs, - "inputs_and_errors_for": func(v interface{}, errs []error) (template.HTML, error) { - return b.Inputs(v, errs...) - }, - } -} - -// ParsingFuncMap is present to make it a little easier to build the input template. -// In order to parse a template that uses the `errors` function, you need to have -// that template defined when the template is parsed. We clearly don't know whether -// a field has an error or not until it is parsed. -func ParsingFuncMap() template.FuncMap { - return template.FuncMap{ - "errors": func() []string { - return nil - }, - } -} - -type FieldError struct { - Field string - Issue string -} - -func (fe FieldError) Error() string { - return fmt.Sprintf("%s: %v", fe.Field, fe.Issue) -} - -// errors will build a map where each key is the field name, and each -// value is a slice of strings representing errors with that field. -func fieldErrors(errs []error) map[string][]string { - ret := make(map[string][]string) - for _, err := range errs { - var fe FieldError - if !errors.As(err, &fe) { - fmt.Println(err, "isnt field error") - continue - } - ret[fe.Field] = append(ret[fe.Field], fe.Issue) - } - return ret -} diff --git a/form/errors.go b/form/errors.go new file mode 100644 index 0000000..52206c4 --- /dev/null +++ b/form/errors.go @@ -0,0 +1,30 @@ +package form + +import ( + "errors" + "fmt" +) + +type FieldError struct { + Field string + Issue string +} + +func (fe FieldError) Error() string { + return fmt.Sprintf("%s: %v", fe.Field, fe.Issue) +} + +// errors will build a map where each key is the field name, and each +// value is a slice of strings representing errors with that field. +func fieldErrors(errs []error) map[string][]string { + ret := make(map[string][]string) + for _, err := range errs { + var fe FieldError + if !errors.As(err, &fe) { + fmt.Println(err, "isnt field error") + continue + } + ret[fe.Field] = append(ret[fe.Field], fe.Issue) + } + return ret +} diff --git a/form/field.templ b/form/field.templ new file mode 100644 index 0000000..e9ce33e --- /dev/null +++ b/form/field.templ @@ -0,0 +1,42 @@ +package form + +import "fmt" + +func (f *field) isCheckbox() bool { + return f.Type == "checkbox" +} + +func (f *field) optionAttributes() templ.Attributes { + attrs := make(map[string]any) + for _, o := range f.Options { + attrs[o] = true + } + return templ.Attributes(attrs) +} + +templ (f *field) item(errors []string) { +
+ + + for _, e := range errors { +

{e}

+ } +
+} \ No newline at end of file diff --git a/form/field_templ.go b/form/field_templ.go new file mode 100644 index 0000000..34266e8 --- /dev/null +++ b/form/field_templ.go @@ -0,0 +1,239 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package form + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "fmt" + +func (f *field) isCheckbox() bool { + return f.Type == "checkbox" +} + +func (f *field) optionAttributes() templ.Attributes { + attrs := make(map[string]any) + for _, o := range f.Options { + attrs[o] = true + } + return templ.Attributes(attrs) +} + +func (f *field) item(errors []string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + var templ_7745c5c3_Var2 = []any{"mb-3", + templ.KV("form-floating", !f.isCheckbox()), + templ.KV("form-check form-switch", f.isCheckbox())} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(f.Label) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `form/field.templ`, Line: 36, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, e := range errors { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(e) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `form/field.templ`, Line: 39, Col: 35} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/form/form.go b/form/form.go new file mode 100644 index 0000000..84758f5 --- /dev/null +++ b/form/form.go @@ -0,0 +1,21 @@ +package form + +import ( + "context" + "io" + + "github.com/a-h/templ" +) + +func Form(v any, errs []error) templ.Component { + fields := fields(v) + errors := fieldErrors(errs) + return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error { + for _, field := range fields { + if err := field.item(errors[field.Name]).Render(ctx, w); err != nil { + return err + } + } + return nil + }) +} diff --git a/form/reflect.go b/form/reflect.go index 4dd4018..604c9e1 100644 --- a/form/reflect.go +++ b/form/reflect.go @@ -1,7 +1,6 @@ package form import ( - "html/template" "reflect" "strings" ) @@ -103,13 +102,6 @@ func (f *field) applyTags(tags map[string]string) { if v, ok := tags["id"]; ok { f.ID = v } - if v, ok := tags["footer"]; ok { - // Probably shouldn't be HTML but whatever. - f.Footer = template.HTML(v) - } - if v, ok := tags["class"]; ok { - f.Class = v - } if v, ok := tags["options"]; ok { f.Options = strings.Split(v, ",") } @@ -143,7 +135,5 @@ type field struct { Type string ID string Options []string - Value interface{} - Footer template.HTML - Class string + Value any } diff --git a/go.mod b/go.mod index f1acb5c..f9a9cdb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23 toolchain go1.23.1 require ( + github.com/a-h/templ v0.2.778 github.com/go-chi/chi/v5 v5.1.0 github.com/gorilla/csrf v1.7.2 github.com/gorilla/schema v1.4.1 diff --git a/go.sum b/go.sum index 82440f9..07d430c 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,12 @@ +github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM= +github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-chi/chi/v5 v5.1.0 h1:acVI1TYaD+hhedDJ3r54HyA6sExp3HfXq7QWEEY/xMw= github.com/go-chi/chi/v5 v5.1.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/csrf v1.7.2 h1:oTUjx0vyf2T+wkrx09Trsev1TE+/EbDAeHtSTbtC2eI= @@ -28,8 +32,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= diff --git a/pages/base.templ b/pages/base.templ new file mode 100644 index 0000000..b78e9b5 --- /dev/null +++ b/pages/base.templ @@ -0,0 +1,77 @@ +package pages + +templ baseWithHeader(header templ.Component) { + + + + + + + Kosten + + + + if header != nil { + @header + } + + + { children... } + + +} + +func base() templ.Component { + return baseWithHeader(nil) +} + +templ navlink(path, descr string) { + +} + +templ navlinks() { + @navlink("/categories", "Kategorien") + @navlink("/recur", "Regelmäßig") +} + +templ navbar() { + /* different inline svgs */ + + + + + + + /* The Navbar */ + +} + +templ content() { + @base() { + @navbar() +
+ {children...} +
+ } +} \ No newline at end of file diff --git a/pages/base_templ.go b/pages/base_templ.go new file mode 100644 index 0000000..112f76e --- /dev/null +++ b/pages/base_templ.go @@ -0,0 +1,264 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package pages + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func baseWithHeader(header templ.Component) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Kosten") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if header != nil { + templ_7745c5c3_Err = header.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func base() templ.Component { + return baseWithHeader(nil) +} + +func navlink(path, descr string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
  • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 = []any{"nav-link", templ.KV("active", isCurrPath(ctx, path))} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(descr) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/base.templ`, Line: 31, Col: 41} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
  • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func navlinks() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = navlink("/categories", "Kategorien").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = navlink("/recur", "Regelmäßig").Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func navbar() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func content() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var9 := templ.GetChildren(ctx) + if templ_7745c5c3_Var9 == nil { + templ_7745c5c3_Var9 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var10 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Err = navbar().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var9.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = base().Render(templ.WithChildren(ctx, templ_7745c5c3_Var10), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pages/login.go b/pages/login.go index 9d8f686..14b1ce1 100644 --- a/pages/login.go +++ b/pages/login.go @@ -56,7 +56,7 @@ type user struct { Password string `form:"type=password;options=required"` RememberMe bool `form:"type=checkbox;value=y;options=checked"` Errors []error `form:"-"` - csrf.Csrf + csrf.CsrfField } func Login() Page { @@ -68,7 +68,7 @@ func Login() Page { } u := user{} u.SetCsrfField(r) - showLoginPage(w, u) + showLoginPage(r, w, u) }) r.Post("/", handleLogin) @@ -102,7 +102,7 @@ func handleLogin(w http.ResponseWriter, r *http.Request) { if !ok { u.Errors = []error{form.FieldError{Field: "Password", Issue: "Invalid"}} - showLoginPage(w, u) + showLoginPage(r, w, u) return } @@ -125,6 +125,6 @@ func handleLogin(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, next, http.StatusFound) } -func showLoginPage(w http.ResponseWriter, u user) { - showTemplate(w, "login", u) +func showLoginPage(r *http.Request, w http.ResponseWriter, u user) { + render(login(u), w, r) } diff --git a/pages/login.templ b/pages/login.templ new file mode 100644 index 0000000..fed611e --- /dev/null +++ b/pages/login.templ @@ -0,0 +1,18 @@ +package pages + +import ( + "gosten/form" +) + +templ login(u user) { + @base() { +
    +
    + + @form.Form(u, u.Errors) + @u.Csrf() + +
    +
    + } +} \ No newline at end of file diff --git a/pages/login_templ.go b/pages/login_templ.go new file mode 100644 index 0000000..617e3b5 --- /dev/null +++ b/pages/login_templ.go @@ -0,0 +1,74 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package pages + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "gosten/form" +) + +func login(u user) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = form.Form(u, u.Errors).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = u.Csrf().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = base().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/pages/page.go b/pages/page.go index 25c2331..6ce8cee 100644 --- a/pages/page.go +++ b/pages/page.go @@ -3,10 +3,10 @@ package pages import ( "context" "gosten/model" - "gosten/templ" "log" "net/http" + "github.com/a-h/templ" "github.com/go-chi/chi/v5" ) @@ -20,39 +20,53 @@ type Page interface { http.Handler } -type dataFunc func(r *http.Request, uid int32) any +type dataFunc[T any] func(r *http.Request, uid int32) T +type tplFunc[T any] func(T) templ.Component -type simplePage struct { - dataFn dataFunc - template string -} - -func (p simplePage) ServeHTTP(w http.ResponseWriter, r *http.Request) { - input := p.dataFn(r, userId(r)) - p.showTemplate(w, input) -} - -func simpleByQuery[T any](tpl string, query func(ctx context.Context, id int32) (T, error)) Page { - dataFn := func(r *http.Request, uid int32) any { +func simpleByQuery[T any](tpl tplFunc[T], query func(ctx context.Context, id int32) (T, error)) Page { + dataFn := func(r *http.Request, uid int32) T { d, _ := query(r.Context(), uid) return d } return simple(tpl, dataFn) } -func simple(tpl string, dataFn dataFunc) Page { - p := simplePage{dataFn, tpl} +func simple[T any](tpl tplFunc[T], dataFn dataFunc[T]) Page { r := chi.NewRouter() - r.Get("/", p.ServeHTTP) + r.Get("/", func(w http.ResponseWriter, r *http.Request) { + input := dataFn(r, userId(r)) + c := tpl(input) + render(c, w, r) + }) return r } -func showTemplate(w http.ResponseWriter, tpl string, data any) { - if err := templ.Lookup(tpl).Execute(w, data); err != nil { - log.Panicf("Executing '%s' with %+v: %v", tpl, data, err) +type ctxPath struct{} + +func render(c templ.Component, w http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(r.Context(), ctxPath{}, r.URL.Path) + if err := c.Render(ctx, w); err != nil { + log.Panic(err.Error()) } } -func (p simplePage) showTemplate(w http.ResponseWriter, data any) { - showTemplate(w, p.template, data) +func isCurrPath(ctx context.Context, path string) bool { + currPath := ctx.Value(ctxPath{}).(string) + if path[0] != '/' { + path = "/" + path + } + + if currPath == "/" { + return path == "/" + } + + if currPath[len(currPath)-1] == '/' { + currPath = currPath[:len(currPath)-1] + } + + if path[len(path)-1] == '/' { + path = path[:len(path)-1] + } + + return currPath == path } diff --git a/pages/pages.go b/pages/pages.go index e965bdd..eb7a3f6 100644 --- a/pages/pages.go +++ b/pages/pages.go @@ -5,22 +5,22 @@ import ( ) func Init() Page { - return simple("index", func(r *http.Request, uid int32) any { + return simple(index, func(r *http.Request, uid int32) string { u, _ := Q.GetUserById(r.Context(), uid) return u.Name }) } func Recur() Page { - return simpleByQuery("recur", Q.GetRecurExpenses) + return simpleByQuery(recur, Q.GetRecurExpenses) } func Categories() Page { - return simpleByQuery("categories", Q.GetCategoriesOrdered) + return simpleByQuery(categories, Q.GetCategoriesOrdered) } func NotFound() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - showTemplate(w, "404", r.RequestURI) + render(notfound(r.RequestURI), w, r) } } diff --git a/pages/pages.templ b/pages/pages.templ new file mode 100644 index 0000000..b9b7489 --- /dev/null +++ b/pages/pages.templ @@ -0,0 +1,46 @@ +package pages + +import "gosten/model" + +templ notfound(uri string) { + @content() { + + } +} + +templ index(user string) { + @content() { + Logged in with user: {user} + } +} + +templ recur(rows []model.GetRecurExpensesRow) { + @content() { + + } +} + +templ categories(rows []model.GetCategoriesOrderedRow) { + @content() { + + } +} \ No newline at end of file diff --git a/pages/pages_templ.go b/pages/pages_templ.go new file mode 100644 index 0000000..263d903 --- /dev/null +++ b/pages/pages_templ.go @@ -0,0 +1,269 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package pages + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "gosten/model" + +func notfound(uri string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
    Seite ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(uri) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/pages.templ`, Line: 12, Col: 47} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" nicht gefunden!
    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func index(user string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var4 := templ.GetChildren(ctx) + if templ_7745c5c3_Var4 == nil { + templ_7745c5c3_Var4 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var5 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Logged in with user: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(user) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `pages/pages.templ`, Line: 20, Col: 30} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var5), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func recur(rows []model.GetRecurExpensesRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var7 := templ.GetChildren(ctx) + if templ_7745c5c3_Var7 == nil { + templ_7745c5c3_Var7 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var8 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var8), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func categories(rows []model.GetCategoriesOrderedRow) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var10 := templ.GetChildren(ctx) + if templ_7745c5c3_Var10 == nil { + templ_7745c5c3_Var10 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var11 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = content().Render(templ.WithChildren(ctx, templ_7745c5c3_Var11), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/templ/404.tpl b/templ/404.tpl deleted file mode 100644 index b0a3658..0000000 --- a/templ/404.tpl +++ /dev/null @@ -1,10 +0,0 @@ -{{define "main"}} - -{{end}} \ No newline at end of file diff --git a/templ/base.tpl b/templ/base.tpl deleted file mode 100644 index 7e42630..0000000 --- a/templ/base.tpl +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - {{block "title" .}}Kosten{{end}} - - - - {{block "head" .}}{{end}} - - -{{block "body" .}} - Dummy Text -{{end}} -{{block "js" .}} -{{end}} - - \ No newline at end of file diff --git a/templ/categories.tpl b/templ/categories.tpl deleted file mode 100644 index 662e1e1..0000000 --- a/templ/categories.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{{define "main"}} - -{{end}} \ No newline at end of file diff --git a/templ/content.tpl b/templ/content.tpl deleted file mode 100644 index 47a7909..0000000 --- a/templ/content.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{{define "body"}} - {{/* different inline svgs */}} - - - - - - - {{/* The Navbar */}} - - - {{/* The Main Content */}} -
    - {{block "main" .}} - Dummy Content - {{end}} -
    -{{end}} \ No newline at end of file diff --git a/templ/form.tpl b/templ/form.tpl deleted file mode 100644 index 4d20557..0000000 --- a/templ/form.tpl +++ /dev/null @@ -1,22 +0,0 @@ -{{define "formItem"}} - {{- $cb := eq .Type "checkbox" -}} -
    - - - - {{range errors}} -

    {{.}}

    - {{end}} - {{with .Footer}}

    {{.}}

    {{end}} -
    -{{end}} \ No newline at end of file diff --git a/templ/index.tpl b/templ/index.tpl deleted file mode 100644 index 76016bb..0000000 --- a/templ/index.tpl +++ /dev/null @@ -1,3 +0,0 @@ -{{define "main"}} - Logged in with user: {{.}} -{{end}} \ No newline at end of file diff --git a/templ/login.tpl b/templ/login.tpl deleted file mode 100644 index 7a9a049..0000000 --- a/templ/login.tpl +++ /dev/null @@ -1,10 +0,0 @@ -{{define "body"}} -
    -
    - - {{inputs_and_errors_for . .Errors}} - {{.CsrfField}} - -
    -
    -{{end}} \ No newline at end of file diff --git a/templ/navlinks.tpl b/templ/navlinks.tpl deleted file mode 100644 index cdd54d7..0000000 --- a/templ/navlinks.tpl +++ /dev/null @@ -1,8 +0,0 @@ -{{define "navlinks"}} - - -{{end}} \ No newline at end of file diff --git a/templ/recur.tpl b/templ/recur.tpl deleted file mode 100644 index 316b768..0000000 --- a/templ/recur.tpl +++ /dev/null @@ -1,9 +0,0 @@ -{{define "main"}} - -{{end}} \ No newline at end of file diff --git a/templ/template.go b/templ/template.go deleted file mode 100644 index 9cefadc..0000000 --- a/templ/template.go +++ /dev/null @@ -1,73 +0,0 @@ -package templ - -import ( - "embed" - "html/template" - "io/fs" - "os" - "sync" - - "gosten/form" -) - -//go:embed *.tpl -var fsEmbed embed.FS - -var templates = make(map[string]*template.Template) -var muTpl sync.RWMutex - -var baseTpl *template.Template - -var isLive = sync.OnceValue(checkLive) - -func init() { - loadBase(fsEmbed) -} - -func checkLive() bool { - return os.Getenv("GOSTEN_LIVE") != "" -} - -func loadBase(fs fs.FS) { - baseTpl = template.Must(template.New("base.tpl"). - Funcs(form.ParsingFuncMap()). - ParseFS(fs, "base.tpl", "form.tpl", "navlinks.tpl", "content.tpl")) - baseTpl.Funcs(form.FuncMap(baseTpl.Lookup("formItem"))) -} - -func Lookup(name string) *template.Template { - if isLive() { - fs := os.DirFS("templ/") - loadBase(fs) - return getTemplate(name, fs) - } - - muTpl.RLock() - tpl := templates[name] - muTpl.RUnlock() - - if tpl == nil { - return parse(name) - } - return tpl -} - -func parse(name string) *template.Template { - muTpl.Lock() - defer muTpl.Unlock() - - if tpl := templates[name]; tpl != nil { - // might've been created by another goroutine - return tpl - } - - t := getTemplate(name, fsEmbed) - templates[name] = t - return t -} - -func getTemplate(name string, fs fs.FS) *template.Template { - b := template.Must(baseTpl.Clone()) - t := template.Must(b.ParseFS(fs, name+".tpl")) - return t -} -- cgit v1.2.3-70-g09d2