package components import ( "fmt" "maps" "strings" "dk/internal/auth" "dk/internal/middleware" "dk/internal/router" "dk/internal/template" "github.com/valyala/fasthttp" ) // PageData holds common page template data type PageData struct { Title string Content string TopNav string LeftSide string RightSide string TotalTime string NumQueries string Version string Build string } // RenderPage renders a page using the layout template with common data and additional custom data func RenderPage(ctx router.Ctx, pageData PageData, additionalData map[string]any) error { if template.Cache == nil || auth.Manager == nil { return fmt.Errorf("template.Cache or auth.Manager not initialized") } layoutTmpl, err := template.Cache.Load("layout.html") if err != nil { return fmt.Errorf("failed to load layout template: %w", err) } // Build the base template data with common fields data := map[string]any{ "title": pageData.Title, "content": pageData.Content, "topnav": GenerateTopNav(ctx), "leftside": pageData.LeftSide, "rightside": pageData.RightSide, "totaltime": middleware.GetRequestTime(ctx), "numqueries": pageData.NumQueries, "version": pageData.Version, "build": pageData.Build, } // Merge in additional data (overwrites common data if keys conflict) maps.Copy(data, additionalData) // Set defaults for empty fields if data["leftside"] == "" { data["leftside"] = LeftAside(ctx) } if data["rightside"] == "" { data["rightside"] = RightAside(ctx) } if data["numqueries"] == "" { data["numqueries"] = "0" } if data["version"] == "" { data["version"] = "1.0.0" } if data["build"] == "" { data["build"] = "dev" } layoutTmpl.WriteTo(ctx, data) return nil } // NewPageData creates a new PageData with sensible defaults func NewPageData(title, content string) PageData { return PageData{ Title: title, Content: content, LeftSide: "", RightSide: "", NumQueries: "0", Version: "1.0.0", Build: "dev", } } // PageTitle returns a proper title for a rendered page. If an empty string // is given, returns "Dragon Knight". If the provided title already has " - Dragon Knight" // at the end, returns title as-is. Appends " - Dragon Knight" to title otherwise. func PageTitle(title string) string { if title == "" { return "Dragon Knight" } if strings.HasSuffix(" - Dragon Knight", title) { return title } return title + " - Dragon Knight" } // RenderPageTemplate is a simplified helper that renders a template within the page layout. // It loads the template, renders it with the provided data, and then renders the full page. // Returns true if successful, false if an error occurred (error is written to response). func RenderPageTemplate(ctx router.Ctx, title, templateName string, data map[string]any) bool { content, err := template.RenderNamed(templateName, data) if err != nil { ctx.SetStatusCode(fasthttp.StatusInternalServerError) fmt.Fprintf(ctx, "Template error: %v", err) return false } pageData := NewPageData(PageTitle(title), content) if err := RenderPage(ctx, pageData, nil); err != nil { ctx.SetStatusCode(fasthttp.StatusInternalServerError) fmt.Fprintf(ctx, "Template error: %v", err) return false } return true }