From a27a2acb76824015655a410ee82c5d9ba9ab1b12 Mon Sep 17 00:00:00 2001 From: w568w <1278297578@qq.com> Date: Mon, 20 Feb 2023 16:01:56 +0800 Subject: [PATCH 1/2] feat: generate sitemap.xml at build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a naïve implementation that only includes article pages in the sitemap. Related to https://github.com/InkProject/ink/issues/116 . --- build.go | 3 +++ go.mod | 2 ++ go.sum | 4 ++++ render.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/build.go b/build.go index 49d8523..45b0f83 100755 --- a/build.go +++ b/build.go @@ -176,6 +176,9 @@ func Build() { // Generate RSS page wg.Add(1) go GenerateRSS(visibleArticles) + // Generate sitemap page + wg.Add(1) + go GenerateSitemap(visibleArticles) // Generate article list JSON wg.Add(1) go GenerateJSON(visibleArticles) diff --git a/go.mod b/go.mod index cf897c7..ed7c4e7 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,8 @@ require ( github.com/facebookgo/testname v0.0.0-20150612200628-5443337c3a12 // indirect github.com/kr/pretty v0.2.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/snabb/diagio v1.0.1 // indirect + github.com/snabb/sitemap v1.0.2 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/sys v0.1.0 // indirect ) diff --git a/go.sum b/go.sum index 3213fb7..4de9872 100644 --- a/go.sum +++ b/go.sum @@ -29,6 +29,10 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/snabb/diagio v1.0.1 h1:l7HODYLuGuPfom3Rbm/HHdp1RdrVyAy5iWEzLkRXlH0= +github.com/snabb/diagio v1.0.1/go.mod h1:ZyGaWFhfBVqstGUw6laYetzeTwZ2xxVPqTALx1QQa1w= +github.com/snabb/sitemap v1.0.2 h1:Qam349AjWdPRxx51Wv8rMoMQuAnj3JcIFahtmZxm7jk= +github.com/snabb/sitemap v1.0.2/go.mod h1:sVjDylXD+ZHu+xplNJZ8o5GMfbxNEx+lGVg7YUuXnac= github.com/urfave/cli/v2 v2.24.2 h1:q1VA+ofZ8SWfEKB9xXHUD4QZaeI9e+ItEqSbfH2JBXk= github.com/urfave/cli/v2 v2.24.2/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= diff --git a/render.go b/render.go index 0544cdf..42ab08b 100755 --- a/render.go +++ b/render.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "encoding/json" "html/template" "os" @@ -9,6 +10,7 @@ import ( "time" "github.com/gorilla/feeds" + "github.com/snabb/sitemap" ) type Data interface{} @@ -130,6 +132,46 @@ func GenerateRSS(articles Collections) { } } +// Generate sitemap page +func GenerateSitemap(articles Collections) { + defer wg.Done() + + if globalConfig.Site.Url != "" { + sm := sitemap.New() + + globalModTime := time.Now() + sm.Add(&sitemap.URL{ + Loc: globalConfig.Site.Url, + LastMod: &globalModTime, + ChangeFreq: sitemap.Weekly, + }) + + for _, item := range articles { + article := item.(Article) + + var lastModTime time.Time + if article.MTime.After(article.Time) { + lastModTime = article.MTime + } else { + lastModTime = article.Time + } + + sm.Add(&sitemap.URL{ + Loc: globalConfig.Site.Url + "/" + article.Link, + LastMod: &lastModTime, + ChangeFreq: sitemap.Weekly, + }) + } + + var sitemap bytes.Buffer + sm.WriteTo(&sitemap) + err := os.WriteFile(filepath.Join(publicPath, "sitemap.xml"), sitemap.Bytes(), 0644) + if err != nil { + Fatal(err.Error()) + } + } +} + // Generate article list page func RenderArticleList(rootPath string, articles Collections, tagName string) { defer wg.Done() From 32ae819bc3ddda14ecfaab351a47deb7c3629b64 Mon Sep 17 00:00:00 2001 From: w568w <1278297578@qq.com> Date: Sat, 4 Mar 2023 17:45:18 +0800 Subject: [PATCH 2/2] fix: panic if theme defines custom copied dirs & files other than bundle This fixes https://github.com/InkProject/ink/issues/110 . --- main.go | 5 ++-- parse.go | 6 ++-- serve.go | 83 ++++++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/main.go b/main.go index 8b8eab1..4a8d2da 100755 --- a/main.go +++ b/main.go @@ -43,6 +43,7 @@ toc: {{.Toc}} ) var globalConfig *GlobalConfig +var themeConfig *ThemeConfig var rootPath string func main() { @@ -187,8 +188,8 @@ func ParseGlobalConfigByCli(c *cli.Context, develop bool) { func ParseGlobalConfigWrap(root string, develop bool) { rootPath = root - globalConfig = ParseGlobalConfig(filepath.Join(rootPath, "config.yml"), develop) - if globalConfig == nil { + globalConfig, themeConfig = ParseGlobalConfig(filepath.Join(rootPath, "config.yml"), develop) + if globalConfig == nil || themeConfig == nil { return } } diff --git a/parse.go b/parse.go index f72032b..d4a2fba 100755 --- a/parse.go +++ b/parse.go @@ -148,12 +148,12 @@ func ReplaceRootFlag(content string) string { return strings.Replace(content, "-/", globalConfig.Site.Root+"/", -1) } -func ParseGlobalConfig(configPath string, develop bool) *GlobalConfig { +func ParseGlobalConfig(configPath string, develop bool) (*GlobalConfig, *ThemeConfig) { var config *GlobalConfig // Parse Global Config data, err := os.ReadFile(configPath) if err != nil { - return nil + return nil, nil } if err = yaml.Unmarshal(data, &config); err != nil { Fatal(err.Error()) @@ -181,7 +181,7 @@ func ParseGlobalConfig(configPath string, develop bool) *GlobalConfig { for item, langItem := range themeConfig.Lang { config.I18n[item] = langItem[config.Site.Lang] } - return config + return config, themeConfig } func ParseThemeConfig(configPath string) *ThemeConfig { diff --git a/serve.go b/serve.go index 6467487..ef130d8 100644 --- a/serve.go +++ b/serve.go @@ -3,6 +3,7 @@ package main import ( "os" "path/filepath" + "reflect" "github.com/InkProject/ink.go" "github.com/facebookgo/symwalk" @@ -13,12 +14,61 @@ import ( var watcher *fsnotify.Watcher var conn *websocket.Conn +func buildWatchList() (files []string, dirs []string) { + dirs = []string{ + filepath.Join(rootPath, "source"), + } + files = []string{ + filepath.Join(rootPath, "config.yml"), + filepath.Join(themePath), + } + + // Add files and directories defined in theme's config.yml to watcher + for _, themeCopiedPath := range themeConfig.Copy { + if themeCopiedPath != "" { + fullPath := filepath.Join(themePath, themeCopiedPath) + s, err := os.Stat(fullPath) + if s == nil || err != nil { + continue + } + + if s.IsDir() { + dirs = append(dirs, fullPath) + } else { + files = append(files, fullPath) + } + } + } + return files, dirs +} + +// Add files and dirs to watcher +func configureWatcher(watcher *fsnotify.Watcher, files []string, dirs []string) error { + for _, source := range dirs { + symwalk.Walk(source, func(path string, f os.FileInfo, err error) error { + if f != nil && f.IsDir() { + if err := watcher.Add(path); err != nil { + Warn(err.Error()) + } + } + return nil + }) + } + for _, source := range files { + if err := watcher.Add(source); err != nil { + Warn(err.Error()) + } + } + return nil +} + func Watch() { // Listen watched file change event if watcher != nil { watcher.Close() } watcher, _ = fsnotify.NewWatcher() + files, dirs := buildWatchList() go func() { for { select { @@ -27,6 +77,15 @@ func Watch() { // Handle when file change Log(event.Name) ParseGlobalConfigWrap(rootPath, true) + + newFiles, newDirs := buildWatchList() + // If file list changed, reconfigure watcher + if !reflect.DeepEqual(files, newFiles) || !reflect.DeepEqual(dirs, newDirs) { + configureWatcher(watcher, newFiles, newDirs) + files = newFiles + dirs = newDirs + } + Build() if conn != nil { if err := conn.WriteMessage(websocket.TextMessage, []byte("change")); err != nil { @@ -39,29 +98,7 @@ func Watch() { } } }() - var dirs = []string{ - filepath.Join(rootPath, "source"), - filepath.Join(themePath, "bundle"), - } - var files = []string{ - filepath.Join(rootPath, "config.yml"), - filepath.Join(themePath), - } - for _, source := range dirs { - symwalk.Walk(source, func(path string, f os.FileInfo, err error) error { - if f.IsDir() { - if err := watcher.Add(path); err != nil { - Warn(err.Error()) - } - } - return nil - }) - } - for _, source := range files { - if err := watcher.Add(source); err != nil { - Warn(err.Error()) - } - } + configureWatcher(watcher, files, dirs) } func Websocket(ctx *ink.Context) {