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 ( )
}