diff --git a/README.md b/README.md index aba29bb..502233f 100644 --- a/README.md +++ b/README.md @@ -607,11 +607,11 @@ Cached pages are looked up for a key that matches the exact, full URL of the giv ### Data -The `Data` field on the `Page` is of type `interface{}` and is what allows your route to pass whatever it requires to the templates, alongside the `Page` itself. +The `Data` field on the `Page` is of type `any` and is what allows your route to pass whatever it requires to the templates, alongside the `Page` itself. ### Forms -The `Form` field on the `Page` is similar to the `Data` field in that it's an `interface{}` type but it's meant to store a struct that represents a form being rendered on the page. +The `Form` field on the `Page` is similar to the `Data` field in that it's an `any` type but it's meant to store a struct that represents a form being rendered on the page. An example of this pattern is: @@ -825,8 +825,8 @@ Once your `Page` is fully built, rendering it via the embedded `Controller` in y ```go func (c *home) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "main" - page.Name = "home" + page.Layout = templates.LayoutMain + page.Name = templates.PageHome return c.RenderPage(ctx, page) } ``` diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 8bcca7c..931180b 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -55,7 +55,7 @@ func (c *Controller) RenderPage(ctx echo.Context, page Page) error { buf, err = c.Container.TemplateRenderer. Parse(). Group("page:htmx"). - Key(page.Name). + Key(string(page.Name)). Base("htmx"). Files( "htmx", @@ -73,8 +73,8 @@ func (c *Controller) RenderPage(ctx echo.Context, page Page) error { buf, err = c.Container.TemplateRenderer. Parse(). Group("page"). - Key(page.Name). - Base(page.Layout). + Key(string(page.Name)). + Base(string(page.Layout)). Files( fmt.Sprintf("layouts/%s", page.Layout), fmt.Sprintf("pages/%s", page.Name), @@ -151,7 +151,7 @@ func (c *Controller) cachePage(ctx echo.Context, page Page, html *bytes.Buffer) } // Redirect redirects to a given route name with optional route parameters -func (c *Controller) Redirect(ctx echo.Context, route string, routeParams ...interface{}) error { +func (c *Controller) Redirect(ctx echo.Context, route string, routeParams ...any) error { url := ctx.Echo().Reverse(route, routeParams...) if htmx.GetRequest(ctx).Boosted { diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index d042c69..2334fa9 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -2,6 +2,7 @@ package controller import ( "context" + "fmt" "net/http" "net/http/httptest" "os" @@ -91,14 +92,14 @@ func TestController_RenderPage(t *testing.T) { } // Check the template cache - parsed, err := c.TemplateRenderer.Load("page", p.Name) + parsed, err := c.TemplateRenderer.Load("page", string(p.Name)) assert.NoError(t, err) // Check that all expected templates were parsed. // This includes the name, layout and all components expectedTemplates := make(map[string]bool) - expectedTemplates[p.Name+config.TemplateExt] = true - expectedTemplates[p.Layout+config.TemplateExt] = true + expectedTemplates[fmt.Sprintf("%s%s", p.Name, config.TemplateExt)] = true + expectedTemplates[fmt.Sprintf("%s%s", p.Layout, config.TemplateExt)] = true components, err := templates.Get().ReadDir("components") require.NoError(t, err) for _, f := range components { @@ -124,13 +125,13 @@ func TestController_RenderPage(t *testing.T) { assert.Equal(t, "trigger", ctx.Response().Header().Get(htmx.HeaderTrigger)) // Check the template cache - parsed, err := c.TemplateRenderer.Load("page:htmx", p.Name) + parsed, err := c.TemplateRenderer.Load("page:htmx", string(p.Name)) assert.NoError(t, err) // Check that all expected templates were parsed. // This includes the name, htmx and all components expectedTemplates := make(map[string]bool) - expectedTemplates[p.Name+config.TemplateExt] = true + expectedTemplates[fmt.Sprintf("%s%s", p.Name, config.TemplateExt)] = true expectedTemplates["htmx"+config.TemplateExt] = true components, err := templates.Get().ReadDir("components") require.NoError(t, err) diff --git a/pkg/controller/form.go b/pkg/controller/form.go index 78680e8..9a357a6 100644 --- a/pkg/controller/form.go +++ b/pkg/controller/form.go @@ -16,7 +16,7 @@ type FormSubmission struct { } // Process processes a submission for a form -func (f *FormSubmission) Process(ctx echo.Context, form interface{}) error { +func (f *FormSubmission) Process(ctx echo.Context, form any) error { f.Errors = make(map[string][]string) f.IsSubmitted = true diff --git a/pkg/controller/page.go b/pkg/controller/page.go index 367c3a9..2e269c9 100644 --- a/pkg/controller/page.go +++ b/pkg/controller/page.go @@ -9,6 +9,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/htmx" "github.com/mikestefanello/pagoda/pkg/msg" + "github.com/mikestefanello/pagoda/templates" echomw "github.com/labstack/echo/v4/middleware" @@ -34,7 +35,7 @@ type Page struct { Context echo.Context // ToURL is a function to convert a route name and optional route parameters to a URL - ToURL func(name string, params ...interface{}) string + ToURL func(name string, params ...any) string // Path stores the path of the current request Path string @@ -44,24 +45,24 @@ type Page struct { // Data stores whatever additional data that needs to be passed to the templates. // This is what the controller uses to pass the content of the page. - Data interface{} + Data any // Form stores a struct that represents a form on the page. // This should be a struct with fields for each form field, using both "form" and "validate" tags // It should also contain a Submission field of type FormSubmission if you wish to have validation // messagesa and markup presented to the user - Form interface{} + Form any // Layout stores the name of the layout base template file which will be used when the page is rendered. // This should match a template file located within the layouts directory inside the templates directory. // The template extension should not be included in this value. - Layout string + Layout templates.Layout // Name stores the name of the page as well as the name of the template file which will be used to render // the content portion of the layout template. // This should match a template file located within the pages directory inside the templates directory. // The template extension should not be included in this value. - Name string + Name templates.Page // IsHome stores whether the requested page is the home page or not IsHome bool diff --git a/pkg/funcmap/funcmap.go b/pkg/funcmap/funcmap.go index 6ee2ad9..71ee254 100644 --- a/pkg/funcmap/funcmap.go +++ b/pkg/funcmap/funcmap.go @@ -39,7 +39,7 @@ func GetFuncMap() template.FuncMap { } // HasField checks if an interface contains a given field -func HasField(v interface{}, name string) bool { +func HasField(v any, name string) bool { rv := reflect.ValueOf(v) if rv.Kind() == reflect.Ptr { rv = rv.Elem() diff --git a/pkg/funcmap/funcmap_test.go b/pkg/funcmap/funcmap_test.go index ac2418d..afc0119 100644 --- a/pkg/funcmap/funcmap_test.go +++ b/pkg/funcmap/funcmap_test.go @@ -32,7 +32,7 @@ func TestLink(t *testing.T) { assert.Equal(t, expected, link) } -func TestGetFuncMap(t *testing.T) { +func TestFile(t *testing.T) { file := File("test.png") expected := fmt.Sprintf("/%s/test.png?v=%s", config.StaticPrefix, CacheBuster) assert.Equal(t, expected, file) diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index cfbdd46..833597c 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -70,6 +70,7 @@ func LoadValidPasswordToken(authClient *services.AuthClient) echo.MiddlewareFunc return next(c) case services.InvalidPasswordTokenError: msg.Warning(c, "The link is either invalid or has expired. Please request a new one.") + // TODO use the const for route name return c.Redirect(http.StatusFound, c.Echo().Reverse("forgot_password")) default: return echo.NewHTTPError( diff --git a/pkg/routes/about.go b/pkg/routes/about.go index 35f80e8..504bebb 100644 --- a/pkg/routes/about.go +++ b/pkg/routes/about.go @@ -4,6 +4,7 @@ import ( "html/template" "github.com/mikestefanello/pagoda/pkg/controller" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -27,8 +28,8 @@ type ( func (c *about) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "main" - page.Name = "about" + page.Layout = templates.LayoutMain + page.Name = templates.PageAbout page.Title = "About" // This page will be cached! diff --git a/pkg/routes/about_test.go b/pkg/routes/about_test.go index 359a737..34574fa 100644 --- a/pkg/routes/about_test.go +++ b/pkg/routes/about_test.go @@ -11,7 +11,7 @@ import ( // this test package func TestAbout_Get(t *testing.T) { doc := request(t). - setRoute("about"). + setRoute(routeNameAbout). get(). assertStatusCode(http.StatusOK). toDoc() diff --git a/pkg/routes/contact.go b/pkg/routes/contact.go index c61fda0..2f663d5 100644 --- a/pkg/routes/contact.go +++ b/pkg/routes/contact.go @@ -5,6 +5,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -23,8 +24,8 @@ type ( func (c *contact) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "main" - page.Name = "contact" + page.Layout = templates.LayoutMain + page.Name = templates.PageContact page.Title = "Contact us" page.Form = contactForm{} diff --git a/pkg/routes/error.go b/pkg/routes/error.go index 0fe9792..98c948c 100644 --- a/pkg/routes/error.go +++ b/pkg/routes/error.go @@ -5,6 +5,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -30,9 +31,9 @@ func (e *errorHandler) Get(err error, ctx echo.Context) { } page := controller.NewPage(ctx) - page.Layout = "main" page.Title = http.StatusText(code) - page.Name = "error" + page.Layout = templates.LayoutMain + page.Name = templates.PageError page.StatusCode = code page.HTMX.Request.Enabled = false diff --git a/pkg/routes/forgot_password.go b/pkg/routes/forgot_password.go index 2d28545..b5c39d2 100644 --- a/pkg/routes/forgot_password.go +++ b/pkg/routes/forgot_password.go @@ -9,6 +9,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" "github.com/mikestefanello/pagoda/pkg/msg" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -26,8 +27,8 @@ type ( func (c *forgotPassword) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "auth" - page.Name = "forgot-password" + page.Layout = templates.LayoutAuth + page.Name = templates.PageForgotPassword page.Title = "Forgot password" page.Form = forgotPasswordForm{} @@ -84,7 +85,7 @@ func (c *forgotPassword) Post(ctx echo.Context) error { ctx.Logger().Infof("generated password reset token for user %d", u.ID) // Email the user - url := ctx.Echo().Reverse("reset_password", u.ID, pt.ID, token) + url := ctx.Echo().Reverse(routeNameResetPassword, u.ID, pt.ID, token) err = c.Container.Mail. Compose(). To(u.Email). diff --git a/pkg/routes/home.go b/pkg/routes/home.go index 7017414..3495d7e 100644 --- a/pkg/routes/home.go +++ b/pkg/routes/home.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/mikestefanello/pagoda/pkg/controller" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -21,8 +22,8 @@ type ( func (c *home) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "main" - page.Name = "home" + page.Layout = templates.LayoutMain + page.Name = templates.PageHome page.Metatags.Description = "Welcome to the homepage." page.Metatags.Keywords = []string{"Go", "MVC", "Web", "Software"} page.Pager = controller.NewPager(ctx, 4) diff --git a/pkg/routes/login.go b/pkg/routes/login.go index 50ba15d..aa03fa2 100644 --- a/pkg/routes/login.go +++ b/pkg/routes/login.go @@ -9,6 +9,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" "github.com/mikestefanello/pagoda/pkg/msg" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -27,8 +28,8 @@ type ( func (c *login) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "auth" - page.Name = "login" + page.Layout = templates.LayoutAuth + page.Name = templates.PageLogin page.Title = "Log in" page.Form = loginForm{} @@ -90,5 +91,5 @@ func (c *login) Post(ctx echo.Context) error { } msg.Success(ctx, fmt.Sprintf("Welcome back, %s. You are now logged in.", u.Name)) - return c.Redirect(ctx, "home") + return c.Redirect(ctx, routeNameHome) } diff --git a/pkg/routes/logout.go b/pkg/routes/logout.go index 18ccdbc..0c2888d 100644 --- a/pkg/routes/logout.go +++ b/pkg/routes/logout.go @@ -17,5 +17,5 @@ func (l *logout) Get(c echo.Context) error { } else { msg.Danger(c, "An error occurred. Please try again.") } - return l.Redirect(c, "home") + return l.Redirect(c, routeNameHome) } diff --git a/pkg/routes/register.go b/pkg/routes/register.go index 85f4b66..ee09dfa 100644 --- a/pkg/routes/register.go +++ b/pkg/routes/register.go @@ -7,6 +7,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" "github.com/mikestefanello/pagoda/pkg/msg" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -27,8 +28,8 @@ type ( func (c *register) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "auth" - page.Name = "register" + page.Layout = templates.LayoutAuth + page.Name = templates.PageRegister page.Title = "Register" page.Form = registerForm{} @@ -75,7 +76,7 @@ func (c *register) Post(ctx echo.Context) error { ctx.Logger().Infof("user created: %s", u.Name) case *ent.ConstraintError: msg.Warning(ctx, "A user with this email address already exists. Please log in.") - return c.Redirect(ctx, "login") + return c.Redirect(ctx, routeNameLogin) default: return c.Fail(err, "unable to create user") } @@ -85,7 +86,7 @@ func (c *register) Post(ctx echo.Context) error { if err != nil { ctx.Logger().Errorf("unable to log in: %v", err) msg.Info(ctx, "Your account has been created.") - return c.Redirect(ctx, "login") + return c.Redirect(ctx, routeNameLogin) } msg.Success(ctx, "Your account has been created. You are now logged in.") @@ -93,7 +94,7 @@ func (c *register) Post(ctx echo.Context) error { // Send the verification email c.sendVerificationEmail(ctx, u) - return c.Redirect(ctx, "home") + return c.Redirect(ctx, routeNameHome) } func (c *register) sendVerificationEmail(ctx echo.Context, usr *ent.User) { @@ -105,7 +106,7 @@ func (c *register) sendVerificationEmail(ctx echo.Context, usr *ent.User) { } // Send the email - url := ctx.Echo().Reverse("verify_email", token) + url := ctx.Echo().Reverse(routeNameVerifyEmail, token) err = c.Container.Mail. Compose(). To(usr.Email). diff --git a/pkg/routes/reset_password.go b/pkg/routes/reset_password.go index ddaf981..957796a 100644 --- a/pkg/routes/reset_password.go +++ b/pkg/routes/reset_password.go @@ -5,6 +5,7 @@ import ( "github.com/mikestefanello/pagoda/pkg/context" "github.com/mikestefanello/pagoda/pkg/controller" "github.com/mikestefanello/pagoda/pkg/msg" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -23,8 +24,8 @@ type ( func (c *resetPassword) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "auth" - page.Name = "reset-password" + page.Layout = templates.LayoutAuth + page.Name = templates.PageResetPassword page.Title = "Reset password" page.Form = resetPasswordForm{} @@ -78,5 +79,5 @@ func (c *resetPassword) Post(ctx echo.Context) error { } msg.Success(ctx, "Your password has been updated.") - return c.Redirect(ctx, "login") + return c.Redirect(ctx, routeNameLogin) } diff --git a/pkg/routes/router.go b/pkg/routes/router.go index 384e760..f7c5825 100644 --- a/pkg/routes/router.go +++ b/pkg/routes/router.go @@ -15,6 +15,24 @@ import ( echomw "github.com/labstack/echo/v4/middleware" ) +const ( + routeNameForgotPassword = "forgot_password" + routeNameForgotPasswordSubmit = "forgot_password.submit" + routeNameLogin = "login" + routeNameLoginSubmit = "login.submit" + routeNameLogout = "logout" + routeNameRegister = "register" + routeNameRegisterSubmit = "register.submit" + routeNameResetPassword = "reset_password" + routeNameResetPasswordSubmit = "reset_password.submit" + routeNameVerifyEmail = "verify_email" + routeNameContact = "contact" + routeNameContactSubmit = "contact.submit" + routeNameAbout = "about" + routeNameHome = "home" + routeNameSearch = "search" +) + // BuildRouter builds the router func BuildRouter(c *services.Container) { // Static files with proper cache control @@ -66,44 +84,44 @@ func BuildRouter(c *services.Container) { func navRoutes(c *services.Container, g *echo.Group, ctr controller.Controller) { home := home{Controller: ctr} - g.GET("/", home.Get).Name = "home" + g.GET("/", home.Get).Name = routeNameHome search := search{Controller: ctr} - g.GET("/search", search.Get).Name = "search" + g.GET("/search", search.Get).Name = routeNameSearch about := about{Controller: ctr} - g.GET("/about", about.Get).Name = "about" + g.GET("/about", about.Get).Name = routeNameAbout contact := contact{Controller: ctr} - g.GET("/contact", contact.Get).Name = "contact" - g.POST("/contact", contact.Post).Name = "contact.post" + g.GET("/contact", contact.Get).Name = routeNameContact + g.POST("/contact", contact.Post).Name = routeNameContactSubmit } func userRoutes(c *services.Container, g *echo.Group, ctr controller.Controller) { logout := logout{Controller: ctr} - g.GET("/logout", logout.Get, middleware.RequireAuthentication()).Name = "logout" + g.GET("/logout", logout.Get, middleware.RequireAuthentication()).Name = routeNameLogout verifyEmail := verifyEmail{Controller: ctr} - g.GET("/email/verify/:token", verifyEmail.Get).Name = "verify_email" + g.GET("/email/verify/:token", verifyEmail.Get).Name = routeNameVerifyEmail noAuth := g.Group("/user", middleware.RequireNoAuthentication()) login := login{Controller: ctr} - noAuth.GET("/login", login.Get).Name = "login" - noAuth.POST("/login", login.Post).Name = "login.post" + noAuth.GET("/login", login.Get).Name = routeNameLogin + noAuth.POST("/login", login.Post).Name = routeNameLoginSubmit register := register{Controller: ctr} - noAuth.GET("/register", register.Get).Name = "register" - noAuth.POST("/register", register.Post).Name = "register.post" + noAuth.GET("/register", register.Get).Name = routeNameRegister + noAuth.POST("/register", register.Post).Name = routeNameRegisterSubmit forgot := forgotPassword{Controller: ctr} - noAuth.GET("/password", forgot.Get).Name = "forgot_password" - noAuth.POST("/password", forgot.Post).Name = "forgot_password.post" + noAuth.GET("/password", forgot.Get).Name = routeNameForgotPassword + noAuth.POST("/password", forgot.Post).Name = routeNameForgotPasswordSubmit resetGroup := noAuth.Group("/password/reset", middleware.LoadUser(c.ORM), middleware.LoadValidPasswordToken(c.Auth), ) reset := resetPassword{Controller: ctr} - resetGroup.GET("/token/:user/:password_token/:token", reset.Get).Name = "reset_password" - resetGroup.POST("/token/:user/:password_token/:token", reset.Post).Name = "reset_password.post" + resetGroup.GET("/token/:user/:password_token/:token", reset.Get).Name = routeNameResetPassword + resetGroup.POST("/token/:user/:password_token/:token", reset.Post).Name = routeNameResetPasswordSubmit } diff --git a/pkg/routes/routes_test.go b/pkg/routes/routes_test.go index cc180bf..97c7d91 100644 --- a/pkg/routes/routes_test.go +++ b/pkg/routes/routes_test.go @@ -70,7 +70,7 @@ func (h *httpRequest) setClient(client http.Client) *httpRequest { return h } -func (h *httpRequest) setRoute(route string, params ...interface{}) *httpRequest { +func (h *httpRequest) setRoute(route string, params ...any) *httpRequest { h.route = srv.URL + c.Web.Reverse(route, params) return h } @@ -122,7 +122,7 @@ func (h *httpResponse) assertStatusCode(code int) *httpResponse { return h } -func (h *httpResponse) assertRedirect(t *testing.T, route string, params ...interface{}) *httpResponse { +func (h *httpResponse) assertRedirect(t *testing.T, route string, params ...any) *httpResponse { assert.Equal(t, c.Web.Reverse(route, params), h.Header.Get("Location")) return h } diff --git a/pkg/routes/search.go b/pkg/routes/search.go index 887baa9..2c83195 100644 --- a/pkg/routes/search.go +++ b/pkg/routes/search.go @@ -5,6 +5,7 @@ import ( "math/rand" "github.com/mikestefanello/pagoda/pkg/controller" + "github.com/mikestefanello/pagoda/templates" "github.com/labstack/echo/v4" ) @@ -22,8 +23,8 @@ type ( func (c *search) Get(ctx echo.Context) error { page := controller.NewPage(ctx) - page.Layout = "main" - page.Name = "search" + page.Layout = templates.LayoutMain + page.Name = templates.PageSearch // Fake search results var results []searchResult diff --git a/pkg/routes/verify_email.go b/pkg/routes/verify_email.go index a744108..9bc6f40 100644 --- a/pkg/routes/verify_email.go +++ b/pkg/routes/verify_email.go @@ -21,7 +21,7 @@ func (c *verifyEmail) Get(ctx echo.Context) error { email, err := c.Container.Auth.ValidateEmailVerificationToken(token) if err != nil { msg.Warning(ctx, "The link is either invalid or has expired.") - return c.Redirect(ctx, "home") + return c.Redirect(ctx, routeNameHome) } // Check if it matches the authenticated user @@ -58,5 +58,5 @@ func (c *verifyEmail) Get(ctx echo.Context) error { } msg.Success(ctx, "Your email has been successfully verified.") - return c.Redirect(ctx, "home") + return c.Redirect(ctx, routeNameHome) } diff --git a/pkg/services/auth.go b/pkg/services/auth.go index c2b06ce..be1bcd3 100644 --- a/pkg/services/auth.go +++ b/pkg/services/auth.go @@ -213,7 +213,7 @@ func (c *AuthClient) GenerateEmailVerificationToken(email string) (string, error // ValidateEmailVerificationToken validates an email verification token and returns the associated email address if // the token is valid and has not expired func (c *AuthClient) ValidateEmailVerificationToken(token string) (string, error) { - t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) { + t, err := jwt.Parse(token, func(t *jwt.Token) (any, error) { if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) } diff --git a/pkg/services/cache.go b/pkg/services/cache.go index c7ead3d..e1f019a 100644 --- a/pkg/services/cache.go +++ b/pkg/services/cache.go @@ -28,7 +28,7 @@ type ( client *CacheClient key string group string - data interface{} + data any expiration time.Duration tags []string } @@ -38,7 +38,7 @@ type ( client *CacheClient key string group string - dataType interface{} + dataType any } // cacheFlush handles chaining a flush operation @@ -128,7 +128,7 @@ func (c *cacheSet) Group(group string) *cacheSet { } // Data sets the data to cache -func (c *cacheSet) Data(data interface{}) *cacheSet { +func (c *cacheSet) Data(data any) *cacheSet { c.data = data return c } @@ -174,13 +174,13 @@ func (c *cacheGet) Group(group string) *cacheGet { } // Type sets the expected Go type of the data being retrieved from the cache -func (c *cacheGet) Type(expectedType interface{}) *cacheGet { +func (c *cacheGet) Type(expectedType any) *cacheGet { c.dataType = expectedType return c } // Fetch fetches the data from the cache -func (c *cacheGet) Fetch(ctx context.Context) (interface{}, error) { +func (c *cacheGet) Fetch(ctx context.Context) (any, error) { if c.key == "" { return nil, errors.New("no cache key specified") } diff --git a/pkg/services/mail.go b/pkg/services/mail.go index 62e481a..2cd1853 100644 --- a/pkg/services/mail.go +++ b/pkg/services/mail.go @@ -30,7 +30,7 @@ type ( subject string body string template string - templateData interface{} + templateData any } ) @@ -128,7 +128,7 @@ func (m *mail) Template(template string) *mail { } // TemplateData sets the data that will be passed to the template specified when calling Template() -func (m *mail) TemplateData(data interface{}) *mail { +func (m *mail) TemplateData(data any) *mail { m.templateData = data return m } diff --git a/pkg/services/tasks.go b/pkg/services/tasks.go index ecb6ea7..8f4db4b 100644 --- a/pkg/services/tasks.go +++ b/pkg/services/tasks.go @@ -23,7 +23,7 @@ type ( task struct { client *TaskClient typ string - payload interface{} + payload any periodic *string queue *string maxRetries *int @@ -75,7 +75,7 @@ func (t *TaskClient) New(typ string) *task { } // Payload sets the task payload data which will be sent to the task handler -func (t *task) Payload(payload interface{}) *task { +func (t *task) Payload(payload any) *task { t.payload = payload return t } diff --git a/pkg/services/template_renderer.go b/pkg/services/template_renderer.go index d21bbb7..dbb4529 100644 --- a/pkg/services/template_renderer.go +++ b/pkg/services/template_renderer.go @@ -155,7 +155,7 @@ func (t *TemplateRenderer) Load(group, key string) (*TemplateParsed, error) { } // Execute executes a template with the given data and provides the output -func (t *TemplateParsed) Execute(data interface{}) (*bytes.Buffer, error) { +func (t *TemplateParsed) Execute(data any) (*bytes.Buffer, error) { if t.Template == nil { return nil, errors.New("cannot execute template: template not initialized") } @@ -209,7 +209,7 @@ func (t *templateBuilder) Store() (*TemplateParsed, error) { // Execute executes the template with the given data. // If the template has not already been cached, this will parse and cache the template -func (t *templateBuilder) Execute(data interface{}) (*bytes.Buffer, error) { +func (t *templateBuilder) Execute(data any) (*bytes.Buffer, error) { tp, err := t.Store() if err != nil { return nil, err diff --git a/pkg/services/validator.go b/pkg/services/validator.go index 863976d..9f45efd 100644 --- a/pkg/services/validator.go +++ b/pkg/services/validator.go @@ -18,7 +18,7 @@ func NewValidator() *Validator { } // Validate validates a struct -func (v *Validator) Validate(i interface{}) error { +func (v *Validator) Validate(i any) error { if err := v.validator.Struct(i); err != nil { return err } diff --git a/templates/templates.go b/templates/templates.go index 257a286..a116ada 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -9,6 +9,28 @@ import ( "runtime" ) +type ( + Layout string + Page string +) + +const ( + LayoutMain Layout = "main" + LayoutAuth Layout = "auth" +) + +const ( + PageAbout Page = "about" + PageContact Page = "contact" + PageError Page = "error" + PageForgotPassword Page = "forgot-password" + PageHome Page = "home" + PageLogin Page = "login" + PageRegister Page = "register" + PageResetPassword Page = "reset-password" + PageSearch Page = "search" +) + //go:embed * var templates embed.FS diff --git a/templates/templates_test.go b/templates/templates_test.go index 44abec0..9b28e34 100644 --- a/templates/templates_test.go +++ b/templates/templates_test.go @@ -1,17 +1,18 @@ package templates import ( + "fmt" "testing" "github.com/stretchr/testify/require" ) func TestGet(t *testing.T) { - _, err := Get().Open("pages/home.gohtml") + _, err := Get().Open(fmt.Sprintf("pages/%s.gohtml", PageHome)) require.NoError(t, err) } func TestGetOS(t *testing.T) { - _, err := GetOS().Open("pages/home.gohtml") + _, err := GetOS().Open(fmt.Sprintf("pages/%s.gohtml", PageHome)) require.NoError(t, err) }