SSG is a Static Site Generator that is only a Static Site Generator. No resumes here! Just a piece of code that generates static files from templates for websites, and can do it live while you develop said templates.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
ssgod/main.go

103 lines
2.9 KiB

package main
import (
"log"
"fmt"
"strings"
"io/fs"
"path/filepath"
"os"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/html/v2"
"zedshaw.games/ssgod/config"
"github.com/yuin/goldmark"
)
func Fail(err error, format string, v ...any) error {
err_format := fmt.Sprintf("ERROR: %v; %s", err, format)
log.Printf(err_format, v...)
return err
}
func ProcessDirEntry(engine *html.Engine, path string, d fs.DirEntry, err error) error {
settings := config.Settings
if !d.IsDir() {
if err != nil { return Fail(err, "path: %s", path); }
dir := filepath.Dir(path)
err = os.MkdirAll(dir, 0750)
if err != nil {
return Fail(err, "making dir %s", dir);
}
split_path := strings.Split(path, string(os.PathSeparator))[1:]
source_name := strings.Join(split_path, "/") // Render wants / even on windows
ext := filepath.Ext(source_name)
source_name, found := strings.CutSuffix(source_name, ext)
if found && source_name != settings.Layout {
prefixed_path := append([]string{settings.Target}, split_path...)
target_path := filepath.Join(prefixed_path...)
_, err := os.Stat(target_path)
if os.IsNotExist(err) {
target_dir := filepath.Dir(target_path)
log.Println("MAKING: ", target_dir)
os.MkdirAll(target_dir, 0750)
}
// generate a data-testid for all pages based on template name
page_id := strings.ReplaceAll(source_name, "/", "-") + "-page"
if ext == ".html" {
out, err := os.OpenFile(target_path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
defer out.Close()
if err != nil { return Fail(err, "writing file %s", target_path) }
err = engine.Render(out, source_name, fiber.Map{"PageId": page_id}, settings.Layout)
if err != nil { return Fail(err, "failed to render %s", path) }
log.Printf("RENDER: %s -> %s", source_name, target_path)
} else if ext == ".md" {
// need to strip the .md and replace with .html
html_name, _ := strings.CutSuffix(target_path, ext)
html_name = fmt.Sprintf("%s.html", html_name)
log.Printf("MARKDOWN: %s -> %s", path, html_name)
out, err := os.OpenFile(html_name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
defer out.Close()
if err != nil { return Fail(err, "writing file %s", target_path) }
input_data, err := os.ReadFile(path)
err = goldmark.Convert(input_data, out)
if err != nil { return Fail(err, "failed to render markdown %s", path) }
}
}
}
return nil
}
func RenderPages() {
engine := html.New(config.Settings.Views, ".html")
engine.Load()
err := filepath.WalkDir(config.Settings.Views,
func (path string, d fs.DirEntry, err error) error {
return ProcessDirEntry(engine, path, d, err)
})
if err != nil { log.Fatalf("can't walk content") }
}
func main() {
config.Load("ssgod.toml")
RenderPages()
}