From 6599839c145a6bf67bd806a9c400a605f89c37dd Mon Sep 17 00:00:00 2001 From: Aleksandr Muravja <aleks.muravja@gmail.com> Date: Sat, 1 Mar 2025 09:31:34 +0100 Subject: [PATCH] Moved to templates --- .dockerignore | 4 +- .gitignore | 2 + server.go | 124 ++++++++++++++++++++++++++---- statik/css/main.css | 2 +- templates/elements/work-item.html | 7 ++ templates/index.html | 4 +- templates/layouts/base.html | 6 +- templates/parts/footer.html | 5 ++ templates/works.html | 13 ++++ 9 files changed, 145 insertions(+), 22 deletions(-) create mode 100644 templates/elements/work-item.html create mode 100644 templates/parts/footer.html create mode 100644 templates/works.html diff --git a/.dockerignore b/.dockerignore index f62f0b7..d55eba6 100644 --- a/.dockerignore +++ b/.dockerignore @@ -7,4 +7,6 @@ # Adding Templates !templates # Additing Statik Files -!statik \ No newline at end of file +!statik +# Adding templates folder +!templates diff --git a/.gitignore b/.gitignore index b15297d..eeae4bc 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ nbdist/ #KDE files .directory +# Binary files +varrior diff --git a/server.go b/server.go index 258bfbe..885b99b 100644 --- a/server.go +++ b/server.go @@ -8,21 +8,40 @@ import ( "log" "net/http" "os" + "path/filepath" ) // PageData holds the data to be passed to the HTML template. type PageData struct { + Title string +} + +type IndexPageData struct { + PageData MyVarValue string } +type WorkPageData struct { + PageData + Name string + Works []Work +} + +type Work struct { + Name string + URL string +} + const ( + elementsDir = "templates/elements" layoutsDir = "templates/layouts" + partsDir = "templates/parts" templatesDir = "templates" extension = "/*.html" ) var ( - //go:embed templates/* templates/layouts/* statik/css/* + //go:embed templates/* templates/elements/* templates/layouts/* templates/parts/* statik/css/* files embed.FS templates map[string]*template.Template ) @@ -36,15 +55,12 @@ func init() { } func main() { - statikFS, err := fs.Sub(files, "statik") - if err != nil { - log.Fatal(err) - } // Define a handler function for the root endpoint ("/"). http.HandleFunc("/", HomePage) + http.HandleFunc("/works", WorksPage) // Serving Static Files as well - http.Handle("/statik", http.FileServer(http.FS(statikFS))) + http.HandleFunc("/statik/", serveStatic) // Define the port to listen on. port := ":1234" @@ -53,7 +69,7 @@ func main() { log.Printf("Starting server on %s...", port) // Start the HTTP server. - err = http.ListenAndServe(port, nil) + err := http.ListenAndServe(port, nil) if err != nil { log.Fatal("Server error:", err) } @@ -72,7 +88,8 @@ func loadTemplates() error { continue } - pt, err := template.ParseFS(files, templatesDir+"/"+tmpl.Name(), layoutsDir+extension) + pt, err := template.ParseFS(files, templatesDir+"/"+tmpl.Name(), + layoutsDir+extension, partsDir+extension, elementsDir+extension) if err != nil { return err } @@ -83,25 +100,35 @@ func loadTemplates() error { } const homePage = "index.html" +const worksPage = "works.html" -func HomePage(w http.ResponseWriter, _ *http.Request) { - t, ok := templates[homePage] +func renderTemplate(w http.ResponseWriter, tmplName string, data any) { + t, ok := templates[tmplName] if !ok { - log.Printf("template %s not found", homePage) + log.Printf("template %s not found", tmplName) + http.Error(w, "Template not found", http.StatusNotFound) return } - // Define the data to be passed to the HTML template. - data := readVar() - // Execute the template and write the result to the response. if err := t.Execute(w, data); err != nil { http.Error(w, "Internal Server Error", http.StatusInternalServerError) log.Printf("Error executing template: %v", err) return } + log.Printf("Serving Template: %s", tmplName) +} + +func HomePage(w http.ResponseWriter, r *http.Request) { + data := readVar() + renderTemplate(w, homePage, data) +} + +func WorksPage(w http.ResponseWriter, r *http.Request) { + data := readMyWorks() + renderTemplate(w, worksPage, data) } -func readVar() PageData { +func readVar() IndexPageData { // Get the value of the environment variable "MY_VAR". myVarValue := os.Getenv("MY_VAR") @@ -111,8 +138,73 @@ func readVar() PageData { } // Define the data to be passed to the HTML template. - data := PageData{ + data := IndexPageData{ + PageData: PageData{Title: "Home Page"}, MyVarValue: myVarValue, } return data } + +func readMyWorks() WorkPageData { + works := []Work{ + {Name: "KLab.sh", URL: "https://klab.sh"}, + {Name: "Hop179", URL: "https://hop179.net"}, + } + return WorkPageData{ + PageData: PageData{Title: "Works Page"}, + Name: "Aleks", + Works: works, + } +} +func serveStatic(w http.ResponseWriter, r *http.Request) { + // Extract the correct file path + filePath := r.URL.Path[len("/statik/"):] + fullPath := "statik/" + filePath + + // Log request details + log.Printf("Serving static file: %s", fullPath) + + // Read the file from embedded FS + content, err := fs.ReadFile(files, fullPath) + if err != nil { + log.Printf("Static file not found: %s", err) + http.NotFound(w, r) + return + } + + // Set the correct Content-Type + mimeType := detectMimeType(filePath) + w.Header().Set("Content-Type", mimeType) + w.WriteHeader(http.StatusOK) + + // Serve the file content + _, writeErr := w.Write(content) + if writeErr != nil { + log.Printf("Error writing response: %s", writeErr) + } +} + +func detectMimeType(file string) string { + switch filepath.Ext(file) { + case ".css": + return "text/css" + case ".js": + return "application/javascript" + case ".png": + return "image/png" + case ".jpg", ".jpeg": + return "image/jpeg" + case ".gif": + return "image/gif" + case ".svg": + return "image/svg+xml" + case ".woff": + return "font/woff" + case ".woff2": + return "font/woff2" + case ".ttf": + return "font/ttf" + default: + return "application/octet-stream" + } +} diff --git a/statik/css/main.css b/statik/css/main.css index 6df7dd7..d2db527 100644 --- a/statik/css/main.css +++ b/statik/css/main.css @@ -1,3 +1,3 @@ body { - background-color: #54b6fc; + background-color: #00fe80; } \ No newline at end of file diff --git a/templates/elements/work-item.html b/templates/elements/work-item.html new file mode 100644 index 0000000..6938ddf --- /dev/null +++ b/templates/elements/work-item.html @@ -0,0 +1,7 @@ +{{define "work-item"}} +<div class="work-item"> + <h3>{{.Name}}</h3> + <p>URL: {{.URL}}</p> + <p><a href="{{.URL}}">View</a></p> +</div> +{{end}} diff --git a/templates/index.html b/templates/index.html index 194b887..fade95b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,6 +1,6 @@ -<!-- Content of index.html: --> {{template "base" .}} {{define "content"}} <h1>Value of MY_VAR: {{.MyVarValue}}</h1> -{{end}} +<a href="/works">Test Works</a> +{{end}} \ No newline at end of file diff --git a/templates/layouts/base.html b/templates/layouts/base.html index 2ac561e..643e411 100644 --- a/templates/layouts/base.html +++ b/templates/layouts/base.html @@ -1,14 +1,16 @@ <!-- Content of base.html: --> {{define "base"}} +<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta charset="utf-8"> - <title>Varrior</title> + <title>Varrior|{{.Title}}</title> <link rel="stylesheet" type="text/css" href="/statik/css/main.css" /> </head> <body> {{template "content" .}} + {{template "footer"}} </body> </html> -{{end}} +{{end}} \ No newline at end of file diff --git a/templates/parts/footer.html b/templates/parts/footer.html new file mode 100644 index 0000000..0217411 --- /dev/null +++ b/templates/parts/footer.html @@ -0,0 +1,5 @@ +{{define "footer"}} +<footer> + <p>Footer</p> +</footer> +{{end}} diff --git a/templates/works.html b/templates/works.html new file mode 100644 index 0000000..356e06c --- /dev/null +++ b/templates/works.html @@ -0,0 +1,13 @@ +{{template "base" .}} +{{define "content"}} +<h1>My Works</h1> +<a href="/">Home</a></br> +{{if .Works}} +<h2>I am {{ .Name }} and I did following projects: </h2></br> +<ul> + {{range .Works}} + <li>{{template "work-item" .}}</li> + {{end}} +</ul> +{{end}} +{{end}} \ No newline at end of file -- GitLab