From b09649cf277c7e5dc735e10cb815597d4c95ca10 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 9 Mar 2024 18:35:28 +0400 Subject: [PATCH] Move templates to use const naming --- pkg/controller/controller.go | 6 +++--- pkg/controller/controller_test.go | 14 ++++++++------ pkg/controller/page.go | 7 ++++--- pkg/funcmap/funcmap.go | 2 +- pkg/funcmap/funcmap_test.go | 2 +- pkg/routes/error.go | 5 +++-- pkg/routes/home.go | 23 ++++++++++------------- pkg/routes/router.go | 6 +++++- pkg/routes/routes_test.go | 7 +++++++ pkg/services/cache.go | 10 +++++----- pkg/services/template_renderer.go | 4 ++-- pkg/services/validator.go | 2 +- templates/layouts/main.tmpl | 4 ++-- templates/pages/error.tmpl | 6 +++--- templates/pages/home.tmpl | 14 ++++++++------ templates/templates.go | 14 ++++++++++++++ templates/templates_test.go | 5 +++-- 17 files changed, 80 insertions(+), 51 deletions(-) create mode 100644 pkg/routes/routes_test.go diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 5d4a08c..8b4246c 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -58,7 +58,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", @@ -76,8 +76,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), diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 52fe17e..3c0b2c0 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" @@ -78,14 +79,15 @@ 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) @@ -114,12 +116,12 @@ func TestController_RenderPage(t *testing.T) { assert.Equal(t, "true", ctx.Response().Header().Get(htmx.HeaderRedirect)) // Check the parsed 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 teh expected templates where parsed + // Check that all the expected templates where parsed 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/page.go b/pkg/controller/page.go index 017a64d..1d63e55 100644 --- a/pkg/controller/page.go +++ b/pkg/controller/page.go @@ -8,6 +8,7 @@ import ( echomw "github.com/labstack/echo/v4/middleware" "github.com/tiny-blob/tinyblob/pkg/htmx" + "github.com/tiny-blob/tinyblob/templates" ) // Page consists of all data that will be used to render a page response for a @@ -41,20 +42,20 @@ type Page struct { // 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 // RequestID stores the ID of the given request. // This will only be populated if the request ID middleware is in effect for the given request. RequestID string // StatusCode stores the HTTP status code to be returned. StatusCode int // 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 string // URL stores the URL of the current request URL string diff --git a/pkg/funcmap/funcmap.go b/pkg/funcmap/funcmap.go index 34760d4..a2bbf7e 100644 --- a/pkg/funcmap/funcmap.go +++ b/pkg/funcmap/funcmap.go @@ -37,7 +37,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 2db7ded..c9990b0 100644 --- a/pkg/funcmap/funcmap_test.go +++ b/pkg/funcmap/funcmap_test.go @@ -33,7 +33,7 @@ func TestLink(t *testing.T) { assert.Equal(t, expected, link) } -func TestGetFuncMap(t *testing.T) { +func TestFile(t *testing.T) { fileName := "favicon.ico" file := File(fileName) expected := fmt.Sprintf("/%s/%s?v=%s", config.StaticPrefix, fileName, CacheBuster) diff --git a/pkg/routes/error.go b/pkg/routes/error.go index 63c7113..b43b31d 100644 --- a/pkg/routes/error.go +++ b/pkg/routes/error.go @@ -7,6 +7,7 @@ import ( "github.com/tiny-blob/tinyblob/pkg/context" "github.com/tiny-blob/tinyblob/pkg/controller" + "github.com/tiny-blob/tinyblob/templates" ) type errorHandler struct { @@ -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/home.go b/pkg/routes/home.go index 6755740..97f9c07 100644 --- a/pkg/routes/home.go +++ b/pkg/routes/home.go @@ -4,6 +4,7 @@ import ( "github.com/labstack/echo/v4" "github.com/tiny-blob/tinyblob/pkg/controller" + "github.com/tiny-blob/tinyblob/templates" ) type ( @@ -15,21 +16,17 @@ type ( func (c *home) Get(ctx echo.Context) error { page := controller.NewPage(ctx) page.Cache.Enabled = true - page.Layout = "main" - page.Name = "home" - page.Metatags.Description = "Instantly execute complex crypto strategies at lightning speed." + page.Layout = templates.LayoutMain + page.Name = templates.PageHome + page.Metatags.Description = "A Player vs Player decentralized prediction market " page.Metatags.Keywords = []string{ - "Crypto trading", - "Solana trading", - "Automated trading", - "Lightning-fast transactions", - "Seamless execution", - "Crypto strategies", - "Drag and drop builder", - "Signal trading", - "Trade executor", + "Crypto", + "PvP trading", + "Decentralized", + "Bitcoin", + "PvP prediction market", } - page.Title = "Crypto tools for professionals" + page.Title = "A PvP prediction marketplace" return c.RenderPage(ctx, page) } diff --git a/pkg/routes/router.go b/pkg/routes/router.go index 00d8a9b..d03cdd5 100644 --- a/pkg/routes/router.go +++ b/pkg/routes/router.go @@ -15,6 +15,10 @@ import ( "github.com/tiny-blob/tinyblob/pkg/services" ) +const ( + routeNameHome = "home" +) + // BuildRouter builds the router. func BuildRouter(c *services.Container) { // Enable cache control for static files. @@ -70,5 +74,5 @@ func BuildRouter(c *services.Container) { func publicRoutes(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 } diff --git a/pkg/routes/routes_test.go b/pkg/routes/routes_test.go new file mode 100644 index 0000000..214f6d0 --- /dev/null +++ b/pkg/routes/routes_test.go @@ -0,0 +1,7 @@ +package routes + +import "testing" + +func TestRoutes(t *testing.T) { + t.Skip("TODO: Implement TestRoutes") +} diff --git a/pkg/services/cache.go b/pkg/services/cache.go index 5599a33..101ba88 100644 --- a/pkg/services/cache.go +++ b/pkg/services/cache.go @@ -37,13 +37,13 @@ type ( client *CacheClient group string key string - dataType interface{} + dataType any } // cacheSet handles chainable cache set operations cacheSet struct { client *CacheClient - data interface{} + data any expiration time.Duration group string key string @@ -96,13 +96,13 @@ func (c *CacheClient) Close() error { } // Data sets the data to the cache -func (c *cacheSet) Data(data interface{}) *cacheSet { +func (c *cacheSet) Data(data any) *cacheSet { c.data = data return c } // Fetch retrieves 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 provided") } @@ -225,7 +225,7 @@ func (c *cacheSet) Tags(tags ...string) *cacheSet { } // Type set the cache type for the expected data -func (c *cacheGet) Type(expectedType interface{}) *cacheGet { +func (c *cacheGet) Type(expectedType any) *cacheGet { c.dataType = expectedType return c } diff --git a/pkg/services/template_renderer.go b/pkg/services/template_renderer.go index 6a0c080..95ba5b7 100644 --- a/pkg/services/template_renderer.go +++ b/pkg/services/template_renderer.go @@ -73,7 +73,7 @@ func (t *templateBuilder) Directories(directories ...string) *templateBuilder { } // Execute executes a template with the given data and returns 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") } @@ -89,7 +89,7 @@ func (t *TemplateParsed) Execute(data interface{}) (*bytes.Buffer, error) { // Execute executes a template with the given data // If the template has not been cached, it will be parsed and cached. -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 d6786b8..7da3346 100644 --- a/pkg/services/validator.go +++ b/pkg/services/validator.go @@ -13,7 +13,7 @@ func NewValidator() *Validator { } } -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/layouts/main.tmpl b/templates/layouts/main.tmpl index 9184e37..89b9029 100644 --- a/templates/layouts/main.tmpl +++ b/templates/layouts/main.tmpl @@ -1,11 +1,11 @@ - + {{template "metatags" .}} {{template "css" .}} {{template "js" .}} - + {{template "content" .}} diff --git a/templates/pages/error.tmpl b/templates/pages/error.tmpl index 86f8bd4..65954a1 100644 --- a/templates/pages/error.tmpl +++ b/templates/pages/error.tmpl @@ -6,11 +6,11 @@

You’re not authorized to view the requested page

{{else if eq .StatusCode 404}}
-

404

-

Click {{link (call .ToURL "home") "here" .Path}} to return home

+

404

+

Click {{link (call .ToURL "home") "here" .Path}} to return home

{{else}}

Something went wrong. Our engineers have been notified. {{end}} -{{end}} \ No newline at end of file +{{end}} diff --git a/templates/pages/home.tmpl b/templates/pages/home.tmpl index be5bbb6..ff65a53 100644 --- a/templates/pages/home.tmpl +++ b/templates/pages/home.tmpl @@ -1,8 +1,10 @@ {{define "content"}}

{{template "header" .}} -
-
Home
+
+
+ Soon. +
{{template "footer" .}}
@@ -14,18 +16,18 @@ TinyBlob
- Launch app + {{link (call .ToURL "dashboard") "Launch App" .Path}}
{{end}} {{define "footer"}} {{end}} diff --git a/templates/templates.go b/templates/templates.go index 8e4dd4e..953f31d 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -9,6 +9,20 @@ import ( "runtime" ) +type ( + Layout string + Page string +) + +const ( + LayoutMain Layout = "main" +) + +const ( + PageError Page = "error" + PageHome Page = "home" +) + //go:embed * var templates embed.FS diff --git a/templates/templates_test.go b/templates/templates_test.go index 21cd0df..7392f39 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 TestGo(t *testing.T) { - _, err := Get().Open("pages/home.tmpl") + _, err := Get().Open(fmt.Sprintf("pages/%s.tmpl", PageHome)) require.NoError(t, err) } func TestGetOS(t *testing.T) { - _, err := GetOS().Open("pages/home.tmpl") + _, err := GetOS().Open(fmt.Sprintf("pages/%s.tmpl", PageHome)) require.NoError(t, err) }