Simplify providing layout component in page

This commit is contained in:
Tony Grosinger 2024-07-27 12:28:45 -07:00
parent 9b057ae87e
commit c68d82c385
11 changed files with 15 additions and 75 deletions

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/a-h/templ"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
@ -79,15 +78,11 @@ func (h *Auth) Routes(g *echo.Group) {
func (h *Auth) ForgotPasswordPage(ctx echo.Context) error { func (h *Auth) ForgotPasswordPage(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Forgot password" p.Title = "Forgot password"
p.LayoutComponent = layouts.Auth
f := form.Get[pages.ForgotPasswordForm](ctx) f := form.Get[pages.ForgotPasswordForm](ctx)
component := pages.ForgotPassword(p, f) component := pages.ForgotPassword(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Auth(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }
@ -146,15 +141,11 @@ func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error {
func (h *Auth) LoginPage(ctx echo.Context) error { func (h *Auth) LoginPage(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Log in" p.Title = "Log in"
p.LayoutComponent = layouts.Auth
f := form.Get[pages.LoginForm](ctx) f := form.Get[pages.LoginForm](ctx)
component := pages.Login(p, f) component := pages.Login(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Auth(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }
@ -219,15 +210,11 @@ func (h *Auth) Logout(ctx echo.Context) error {
func (h *Auth) RegisterPage(ctx echo.Context) error { func (h *Auth) RegisterPage(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Register" p.Title = "Register"
p.LayoutComponent = layouts.Auth
f := form.Get[pages.RegisterForm](ctx) f := form.Get[pages.RegisterForm](ctx)
component := pages.Register(p, f) component := pages.Register(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Auth(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }
@ -328,15 +315,11 @@ func (h *Auth) sendVerificationEmail(ctx echo.Context, usr sqlc.User) {
func (h *Auth) ResetPasswordPage(ctx echo.Context) error { func (h *Auth) ResetPasswordPage(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Reset password" p.Title = "Reset password"
p.LayoutComponent = layouts.Auth
f := form.Get[pages.ResetPasswordForm](ctx) f := form.Get[pages.ResetPasswordForm](ctx)
component := pages.ResetPassword(p, f) component := pages.ResetPassword(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Auth(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"time" "time"
"github.com/a-h/templ"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"git.grosinger.net/tgrosinger/saasitone/pkg/form" "git.grosinger.net/tgrosinger/saasitone/pkg/form"
@ -44,6 +43,7 @@ func (h *Cache) Routes(g *echo.Group) {
func (h *Cache) Page(ctx echo.Context) error { func (h *Cache) Page(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Set a cache entry" p.Title = "Set a cache entry"
p.LayoutComponent = layouts.Main
// Fetch the value from the cache // Fetch the value from the cache
value, err := h.cache. value, err := h.cache.
@ -66,11 +66,6 @@ func (h *Cache) Page(ctx echo.Context) error {
f := form.Get[pages.CacheForm](ctx) f := form.Get[pages.CacheForm](ctx)
component := pages.Cache(p, f, valueStrPtr) component := pages.Cache(p, f, valueStrPtr)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -3,7 +3,6 @@ package handlers
import ( import (
"fmt" "fmt"
"github.com/a-h/templ"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
@ -44,15 +43,11 @@ func (h *Contact) Routes(g *echo.Group) {
func (h *Contact) Page(ctx echo.Context) error { func (h *Contact) Page(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Contact us" p.Title = "Contact us"
p.LayoutComponent = layouts.Main
f := form.Get[pages.ContactForm](ctx) f := form.Get[pages.ContactForm](ctx)
component := pages.Contact(p, f) component := pages.Contact(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -3,7 +3,6 @@ package handlers
import ( import (
"net/http" "net/http"
"github.com/a-h/templ"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/context"
@ -42,14 +41,11 @@ func (e *Error) Page(err error, ctx echo.Context) {
p := page.New(ctx) p := page.New(ctx)
p.Title = http.StatusText(code) p.Title = http.StatusText(code)
p.StatusCode = code p.StatusCode = code
p.LayoutComponent = layouts.Main
p.HTMX.Request.Enabled = false p.HTMX.Request.Enabled = false
component := pages.Error(p) component := pages.Error(p)
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
if err = e.RenderPageTempl(ctx, p, component); err != nil { if err = e.RenderPageTempl(ctx, p, component); err != nil {
log.Ctx(ctx).Error("failed to render error page", log.Ctx(ctx).Error("failed to render error page",
"error", err, "error", err,

View File

@ -1,7 +1,6 @@
package handlers package handlers
import ( import (
"github.com/a-h/templ"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"git.grosinger.net/tgrosinger/saasitone/pkg/page" "git.grosinger.net/tgrosinger/saasitone/pkg/page"
@ -42,21 +41,18 @@ func (h *Pages) Home(ctx echo.Context) error {
p.Metatags.Description = "Welcome to the homepage." p.Metatags.Description = "Welcome to the homepage."
p.Metatags.Keywords = []string{"Go", "MVC", "Web", "Software"} p.Metatags.Keywords = []string{"Go", "MVC", "Web", "Software"}
p.Pager = page.NewPager(ctx, 4) p.Pager = page.NewPager(ctx, 4)
p.LayoutComponent = layouts.Main
data := h.Post.FetchAll(&p.Pager) data := h.Post.FetchAll(&p.Pager)
component := pages.Home(p, data) component := pages.Home(p, data)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }
func (h *Pages) About(ctx echo.Context) error { func (h *Pages) About(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "About" p.Title = "About"
p.LayoutComponent = layouts.Main
// This page will be cached! // This page will be cached!
p.Cache.Enabled = true p.Cache.Enabled = true
@ -93,11 +89,5 @@ func (h *Pages) About(ctx echo.Context) error {
} }
component := pages.About(p, data) component := pages.About(p, data)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"github.com/a-h/templ"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"git.grosinger.net/tgrosinger/saasitone/pkg/page" "git.grosinger.net/tgrosinger/saasitone/pkg/page"
@ -36,6 +35,7 @@ func (h *Search) Routes(g *echo.Group) {
func (h *Search) Page(ctx echo.Context) error { func (h *Search) Page(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.LayoutComponent = layouts.Main
// Fake search results // Fake search results
var results []pages.SearchResult var results []pages.SearchResult
@ -52,11 +52,5 @@ func (h *Search) Page(ctx echo.Context) error {
} }
component := pages.Search(p, results) component := pages.Search(p, results)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/a-h/templ"
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/mikestefanello/backlite" "github.com/mikestefanello/backlite"
@ -48,15 +47,10 @@ func (h *Task) Routes(g *echo.Group) {
func (h *Task) Page(ctx echo.Context) error { func (h *Task) Page(ctx echo.Context) error {
p := page.New(ctx) p := page.New(ctx)
p.Title = "Create a task" p.Title = "Create a task"
p.LayoutComponent = layouts.Main
f := form.Get[pages.TaskForm](ctx) f := form.Get[pages.TaskForm](ctx)
component := pages.Task(p, f) component := pages.Task(p, f)
// TODO: This can be reused
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
return h.RenderPageTempl(ctx, p, component) return h.RenderPageTempl(ctx, p, component)
} }

View File

@ -5,7 +5,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/a-h/templ"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -24,9 +23,7 @@ func TestServeCachedPage(t *testing.T) {
p.StatusCode = http.StatusCreated p.StatusCode = http.StatusCreated
p.Headers["a"] = "b" p.Headers["a"] = "b"
p.Headers["c"] = "d" p.Headers["c"] = "d"
p.LayoutComponent = func(content templ.Component) templ.Component { p.LayoutComponent = layouts.HTMX
return layouts.HTMX(p, content)
}
err := c.TemplateRenderer.RenderPageTempl(ctx, p, pages.Cache(p, &pages.CacheForm{}, nil)) err := c.TemplateRenderer.RenderPageTempl(ctx, p, pages.Cache(p, &pages.CacheForm{}, nil))
output := rec.Body.Bytes() output := rec.Body.Bytes()
require.NoError(t, err) require.NoError(t, err)

View File

@ -41,7 +41,7 @@ type Page struct {
// ToURL is a function to convert a route name and optional route parameters to a URL // 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 ...interface{}) string
LayoutComponent func(content templ.Component) templ.Component LayoutComponent func(p Page, content templ.Component) templ.Component
// IsHome stores whether the requested page is the home page or not // IsHome stores whether the requested page is the home page or not
IsHome bool IsHome bool

View File

@ -110,7 +110,7 @@ func (t *TemplateRenderer) RenderPageTempl(ctx echo.Context, page page.Page, con
// Only partial content should be rendered. // Only partial content should be rendered.
err = content.Render(ctx.Request().Context(), &buf) err = content.Render(ctx.Request().Context(), &buf)
} else { } else {
err = page.LayoutComponent(content).Render(ctx.Request().Context(), &buf) err = page.LayoutComponent(page, content).Render(ctx.Request().Context(), &buf)
} }
if err != nil { if err != nil {
return echo.NewHTTPError( return echo.NewHTTPError(

View File

@ -5,7 +5,6 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/a-h/templ"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -87,16 +86,13 @@ func TestTemplateRenderer_RenderPage(t *testing.T) {
t.Run("htmx rendering", func(t *testing.T) { t.Run("htmx rendering", func(t *testing.T) {
ctx, _, p := setup() ctx, _, p := setup()
p.LayoutComponent = layouts.Main
p.HTMX.Request.Enabled = true p.HTMX.Request.Enabled = true
p.HTMX.Response = &htmx.Response{ p.HTMX.Response = &htmx.Response{
Trigger: "trigger", Trigger: "trigger",
} }
component := pages.Home(p, []models.Post{}) component := pages.Home(p, []models.Post{})
p.LayoutComponent = func(content templ.Component) templ.Component {
return layouts.Main(p, content)
}
err := c.TemplateRenderer.RenderPageTempl(ctx, p, component) err := c.TemplateRenderer.RenderPageTempl(ctx, p, component)
require.NoError(t, err) require.NoError(t, err)