0
0
Fork 0
zero-blog/main.go

95 lines
2.8 KiB
Go

package main
import (
"bytes"
"embed"
"flag"
"html/template"
"io/fs"
"log"
"net/http"
"os"
"path"
)
var (
listen = flag.String("listen", "127.0.0.1:9292", "set the listen address for the web server")
withUnpublished = flag.Bool("with-unpublished", false, "set to true when unpublished content should also be rendered")
defaultTemplate = flag.String("default-template", "default.html", "the name of the default template to use for content pages")
prefix = flag.String("prefix", "/", "the prefix to use for all paths")
dumpFiles = flag.String("dump-files", "", "set an output directory to dump all files into")
//go:embed files templates
embeddedDir embed.FS
)
func main() {
flag.Parse()
// templates
tmplDir, err := fs.Sub(embeddedDir, "templates")
if err != nil {
log.Fatalf("could not access template directory: %s", err)
}
tmpls, err := template.ParseFS(tmplDir, "*.html")
if err != nil {
log.Fatalf("could not parse templates: %s", err)
}
// posts
contentDir, err := fs.Sub(embeddedDir, "files/content")
if err != nil {
log.Fatalf("could not access files dir: %s", err)
}
catalog, err := NewCatalog(contentDir, CatalogOptions{
WithUnpublished: *withUnpublished,
DefaultTemplate: *defaultTemplate,
})
if err != nil {
log.Fatalf("could not parse catalog: %s", err)
}
pages, err := catalog.Render(tmpls)
if err != nil {
log.Fatalf("rendering pages failed: %s", err)
}
catalog = nil
// When in dump mode export everything and then end program.
if *dumpFiles != "" {
if err := os.MkdirAll(*dumpFiles, 0755); err != nil && !os.IsExist(err) {
log.Fatalf("could not create target directory: %s", err)
}
realPath := ""
for filePath, cont := range pages {
realPath = path.Join(*dumpFiles, *prefix, filePath)
if err := os.MkdirAll(path.Dir(realPath), 0755); err != nil && !os.IsExist(err) {
log.Fatalf("could not create parent directories for '%s': %s", realPath, err)
}
if err := os.WriteFile(realPath, cont.Content, 0644); err != nil {
log.Fatalf("could not write file '%s': %s", realPath, err)
}
}
return
}
for path, cont := range pages {
log.Printf("adding '%s' to serve", *prefix+path)
handleCont := cont
http.DefaultServeMux.HandleFunc(*prefix+path, func(w http.ResponseWriter, r *http.Request) {
for key, header := range handleCont.Header {
w.Header().Add(key, header[0])
}
http.ServeContent(w, r, "", handleCont.Modified, bytes.NewReader(handleCont.Content))
return
})
}
// static files
static, err := fs.Sub(embeddedDir, "files/static")
if err != nil {
log.Fatalf("directory `files/static` could not be extracted: %s", err)
}
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(static))))
log.Fatalf("server stopped: %s", http.ListenAndServe(*listen, nil))
}