diff --git a/go.mod b/go.mod index f388207..300a609 100644 --- a/go.mod +++ b/go.mod @@ -58,7 +58,7 @@ require ( golang.org/x/mod v0.4.1 // indirect golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c - golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b // indirect + golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 // indirect golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect golang.org/x/text v0.3.5 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect diff --git a/go.sum b/go.sum index 84b9189..f4d78b8 100644 --- a/go.sum +++ b/go.sum @@ -411,8 +411,8 @@ golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b h1:ggRgirZABFolTmi3sn6Ivd9SipZwLedQ5wR0aAKnFxU= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M= diff --git a/sitemap.go b/sitemap.go index 0a9a376..2f44933 100644 --- a/sitemap.go +++ b/sitemap.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "net/http" "time" @@ -11,29 +12,132 @@ import ( const sitemapPath = "/sitemap.xml" func serveSitemap(w http.ResponseWriter, r *http.Request) { - posts, err := getPosts(&postsRequestConfig{ - status: statusPublished, - }) - if err != nil { - serveError(w, r, err.Error(), http.StatusInternalServerError) - return - } sm := sitemap.New() sm.Minify = true - for _, p := range posts { - item := &sitemap.URL{ - Loc: p.fullURL()} - var lastMod time.Time - if p.Updated != "" { - lastMod, _ = dateparse.ParseLocal(p.Updated) + // Blogs + for b, bc := range appConfig.Blogs { + // Blog + blogPath := bc.Path + if blogPath == "/" { + blogPath = "" } - if p.Published != "" && lastMod.IsZero() { - lastMod, _ = dateparse.ParseLocal(p.Published) + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + blogPath, + }) + // Sections + for _, section := range bc.Sections { + if section.Name != "" { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + bc.getRelativePath("/"+section.Name), + }) + } } - if !lastMod.IsZero() { - item.LastMod = &lastMod + // Taxonomies + for _, taxonomy := range bc.Taxonomies { + if taxonomy.Name != "" { + // Taxonomy + taxPath := bc.getRelativePath("/" + taxonomy.Name) + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + taxPath, + }) + // Values + if taxValues, err := allTaxonomyValues(b, taxonomy.Name); err == nil { + for _, tv := range taxValues { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + taxPath + "/" + urlize(tv), + }) + } + } + } + } + // Year / month archives + if dates, err := allPublishedDates(b); err == nil { + already := map[string]bool{} + for _, d := range dates { + // Year + yearPath := bc.getRelativePath("/" + fmt.Sprintf("%0004d", d.year)) + if !already[yearPath] { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + yearPath, + }) + already[yearPath] = true + } + // Specific month + monthPath := yearPath + "/" + fmt.Sprintf("%02d", d.month) + if !already[monthPath] { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + monthPath, + }) + already[monthPath] = true + } + // Specific day + dayPath := monthPath + "/" + fmt.Sprintf("%02d", d.day) + if !already[dayPath] { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + dayPath, + }) + already[dayPath] = true + } + // Generic month + genericMonthPath := blogPath + "/x/" + fmt.Sprintf("%02d", d.month) + if !already[genericMonthPath] { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + genericMonthPath, + }) + already[genericMonthPath] = true + } + // Specific day + genericMonthDayPath := genericMonthPath + "/" + fmt.Sprintf("%02d", d.day) + if !already[genericMonthDayPath] { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + genericMonthDayPath, + }) + already[genericMonthDayPath] = true + } + } + } + // Photos + if bc.Photos != nil && bc.Photos.Enabled { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + bc.getRelativePath(bc.Photos.Path), + }) + } + // Search + if bc.Search != nil && bc.Search.Enabled { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + bc.getRelativePath(bc.Search.Path), + }) + } + // Stats + if bc.BlogStats != nil && bc.BlogStats.Enabled { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + bc.getRelativePath(bc.BlogStats.Path), + }) + } + // Custom pages + for _, cp := range bc.CustomPages { + sm.Add(&sitemap.URL{ + Loc: appConfig.Server.PublicAddress + cp.Path, + }) } - sm.Add(item) } + // Posts + if posts, err := getPosts(&postsRequestConfig{status: statusPublished}); err == nil { + for _, p := range posts { + item := &sitemap.URL{Loc: p.fullURL()} + var lastMod time.Time + if p.Updated != "" { + lastMod, _ = dateparse.ParseLocal(p.Updated) + } + if p.Published != "" && lastMod.IsZero() { + lastMod, _ = dateparse.ParseLocal(p.Published) + } + if !lastMod.IsZero() { + item.LastMod = &lastMod + } + sm.Add(item) + } + } + // Write... _, _ = sm.WriteTo(w) // Already minified }