diff --git a/PLAN.md b/PLAN.md index 2bddf56..0fa5736 100644 --- a/PLAN.md +++ b/PLAN.md @@ -10,7 +10,7 @@ ## Current Status - [x] Project backbone exists (HTTP server, graceful shutdown, config reading). - [x] Markdown parsing logic implemented (using goldmark). -- [ ] HTML Template engine integrated (Hugo-like theme selection). +- [x] HTML Template engine integrated (Hugo-like theme selection). - [ ] PDF Generation implemented (Pure Go library selected and integrated). - [x] CLI Mode (`gocv`) generates static files to `./output` and exits. - [ ] Serve Mode (`gocv serve`) hosts HTML and serves PDF on demand. @@ -19,11 +19,12 @@ ## Active Task - [x] Analyze existing backbone code and integrate Markdown parsing. -- [ ] Integrate HTML template engine with theme selection. +- [x] Integrate HTML template engine with theme selection. +- [ ] Implement Serve Mode with file watching for live reload. ## Known Issues / Blockers - [ ] Identify best Pure Go PDF library that supports HTML/CSS (or define CSS subset). -- [ ] Current output is raw HTML fragments without full HTML document structure. +- [x] Current output is raw HTML fragments without full HTML document structure. ## Completed Log - [x] Initial project structure defined. @@ -31,3 +32,6 @@ - [x] CLI mode vs Serve mode distinction implemented (checks os.Args[1] for "serve"). - [x] Content reading from `./content` directory implemented. - [x] Markdown to HTML conversion using goldmark library. +- [x] Theme system with templates/themes/{theme}/base.html structure. +- [x] Config.yaml theme setting (defaults to "default"). +- [x] Output now generates complete HTML documents with styling. diff --git a/content.go b/content.go index 4153d58..aaf1842 100644 --- a/content.go +++ b/content.go @@ -3,6 +3,7 @@ package main import ( "bytes" "fmt" + "html/template" "os" "path/filepath" "strings" @@ -18,6 +19,12 @@ type ContentFile struct { HTML string // Converted HTML } +// PageData represents data passed to the template +type PageData struct { + Title string + Content template.HTML +} + // generateOutput reads content from ./content, processes it, and writes to ./output func generateOutput() error { // Ensure content directory exists @@ -30,6 +37,13 @@ func generateOutput() error { return fmt.Errorf("failed to create output directory: %w", err) } + // Load the theme template + themePath := filepath.Join("themes", ws.Theme, "base.html") + tmpl, err := template.ParseFiles(themePath) + if err != nil { + return fmt.Errorf("failed to load theme template %s: %w", themePath, err) + } + // Read all markdown files from content directory files, err := readContentFiles() if err != nil { @@ -52,12 +66,22 @@ func generateOutput() error { } file.HTML = html + // Apply theme template + var output bytes.Buffer + data := PageData{ + Title: file.Name + " - " + ws.AppName, + Content: template.HTML(file.HTML), + } + if err := tmpl.Execute(&output, data); err != nil { + return fmt.Errorf("failed to execute template for %s: %w", file.SourcePath, err) + } + // Write output outputFile := filepath.Join(outputPath, file.Name+".html") - if err := os.WriteFile(outputFile, []byte(html), 0644); err != nil { + if err := os.WriteFile(outputFile, output.Bytes(), 0644); err != nil { return fmt.Errorf("failed to write %s: %w", outputFile, err) } - fmt.Printf(" -> Written: %s\n", outputPath) + fmt.Printf(" -> Written: %s\n", outputFile) } return nil diff --git a/themes/default/base.html b/themes/default/base.html new file mode 100644 index 0000000..5fc545f --- /dev/null +++ b/themes/default/base.html @@ -0,0 +1,42 @@ + + + + + + {{.Title}} + + + +{{.Content}} + + \ No newline at end of file diff --git a/themes/default/baseof.html b/themes/default/baseof.html new file mode 100644 index 0000000..53026b4 --- /dev/null +++ b/themes/default/baseof.html @@ -0,0 +1,53 @@ + + + + + + {{ .Title }} + + + +
+ {{ .Content }} +
+ + \ No newline at end of file diff --git a/type_webserver.go b/type_webserver.go index 5218cde..9128b63 100644 --- a/type_webserver.go +++ b/type_webserver.go @@ -12,6 +12,7 @@ import ( type WebServer struct { HTTPServer *http.Server AppName string `yaml:"app_name"` + Theme string `yaml:"theme"` Listen WSListen `yaml:"listen"` } @@ -27,6 +28,8 @@ func (s *WebServer) Initialize() { Port: "80", } s.AppName = "Go Template Container Web Server" + s.Theme = "default" + s.Theme = "default" // Attempt to read the config file (try both config.yml and config.yaml) var configFile []byte