diff --git a/httpRouters.go b/httpRouters.go index 5eef059..2cfcc47 100644 --- a/httpRouters.go +++ b/httpRouters.go @@ -145,7 +145,7 @@ func (a *goBlog) blogRouter(blog string, conf *configBlog) func(r chi.Router) { r.Group(a.blogTaxonomiesRouter(conf)) // Dates - r.Group(a.blogDatesRouter(conf)) + r.With(a.privateModeHandler, a.cacheMiddleware).Group(a.blogDatesRouter(conf)) // Photos r.Group(a.blogPhotosRouter(conf)) @@ -209,10 +209,15 @@ func (a *goBlog) blogSectionsRouter(conf *configBlog) func(r chi.Router) { r.Group(func(r chi.Router) { secPath := conf.getRelativePath(section.Name) r.Use(middleware.WithValue(indexConfigKey, &indexConfig{ - path: secPath, - section: section, + path: secPath, + section: section, + title: section.Title, + description: section.Description, })) - r.Get(secPath, a.serveIndex) + r.Route(secPath, func(r chi.Router) { + r.Get("/", a.serveIndex) + r.Group(a.blogDatesRouter(conf)) + }) r.Get(secPath+feedPath, a.serveIndex) r.Get(secPath+paginationPath, a.serveIndex) }) @@ -246,11 +251,6 @@ func (a *goBlog) blogTaxonomiesRouter(conf *configBlog) func(r chi.Router) { // Blog - Dates func (a *goBlog) blogDatesRouter(conf *configBlog) func(r chi.Router) { return func(r chi.Router) { - r.Use( - a.privateModeHandler, - a.cacheMiddleware, - ) - yearPath := conf.getRelativePath(`/{year:(x|\d{4})}`) r.Get(yearPath, a.serveDate) r.Get(yearPath+feedPath, a.serveDate) diff --git a/posts.go b/posts.go index 7d2ffe9..efa9a06 100644 --- a/posts.go +++ b/posts.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "net/http" + "path" "reflect" "strings" "time" @@ -219,7 +220,32 @@ func (a *goBlog) serveDeleted(w http.ResponseWriter, r *http.Request) { } func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) { - var year, month, day int + year, month, day, title, datePath := a.extractDate(r) + if year == 0 && month == 0 && day == 0 { + a.serve404(w, r) + return + } + var ic *indexConfig + if cv := r.Context().Value(indexConfigKey); cv != nil { + origIc := *(cv.(*indexConfig)) + copyIc := origIc + ic = ©Ic + ic.path = path.Join(ic.path, datePath) + ic.title = fmt.Sprintf("%s: %s", ic.title, title) + } else { + _, bc := a.getBlog(r) + ic = &indexConfig{ + path: bc.getRelativePath(datePath), + title: title, + } + } + ic.year = year + ic.month = month + ic.day = day + a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, ic))) +} + +func (a *goBlog) extractDate(r *http.Request) (year, month, day int, title, datePath string) { if ys := chi.URLParam(r, "year"); ys != "" && ys != "x" { year = stringToInt(ys) } @@ -229,38 +255,29 @@ func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) { if ds := chi.URLParam(r, "day"); ds != "" { day = stringToInt(ds) } - if year == 0 && month == 0 && day == 0 { - a.serve404(w, r) - return - } - title, dPath := bufferpool.Get(), bufferpool.Get() + titleBuf, pathBuf := bufferpool.Get(), bufferpool.Get() + defer bufferpool.Put(titleBuf, pathBuf) if year != 0 { - _, _ = fmt.Fprintf(title, "%0004d", year) - _, _ = fmt.Fprintf(dPath, "%0004d", year) + _, _ = fmt.Fprintf(titleBuf, "%0004d", year) + _, _ = fmt.Fprintf(pathBuf, "%0004d", year) } else { - _, _ = title.WriteString("XXXX") - _, _ = dPath.WriteString("x") + _, _ = titleBuf.WriteString("XXXX") + _, _ = pathBuf.WriteString("x") } if month != 0 { - _, _ = fmt.Fprintf(title, "-%02d", month) - _, _ = fmt.Fprintf(dPath, "/%02d", month) + _, _ = fmt.Fprintf(titleBuf, "-%02d", month) + _, _ = fmt.Fprintf(pathBuf, "/%02d", month) } else if day != 0 { - _, _ = title.WriteString("-XX") - _, _ = dPath.WriteString("/x") + _, _ = titleBuf.WriteString("-XX") + _, _ = pathBuf.WriteString("/x") } if day != 0 { - _, _ = fmt.Fprintf(title, "-%02d", day) - _, _ = fmt.Fprintf(dPath, "/%02d", day) + _, _ = fmt.Fprintf(titleBuf, "-%02d", day) + _, _ = fmt.Fprintf(pathBuf, "/%02d", day) } - _, bc := a.getBlog(r) - a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{ - path: bc.getRelativePath(dPath.String()), - year: year, - month: month, - day: day, - title: title.String(), - }))) - bufferpool.Put(title, dPath) + title = titleBuf.String() + datePath = pathBuf.String() + return } type indexConfig struct { @@ -324,17 +341,17 @@ func (a *goBlog) serveIndex(w http.ResponseWriter, r *http.Request) { a.serveError(w, r, err.Error(), http.StatusInternalServerError) return } - // Meta - title := ic.title - description := ic.description - if ic.tax != nil { + // Title + var title string + if ic.title != "" { + title = ic.title + } else if ic.tax != nil { title = fmt.Sprintf("%s: %s", ic.tax.Title, ic.taxValue) - } else if ic.section != nil { - title = ic.section.Title - description = ic.section.Description } else if search != "" { title = fmt.Sprintf("%s: %s", bc.Search.Title, search) } + // Description + description := ic.description // Check if feed if ft := feedType(chi.URLParam(r, "feed")); ft != noFeed { a.generateFeed(blog, ft, w, r, posts, title, description) diff --git a/sitemap.go b/sitemap.go index 2a9a024..4aa5b6f 100644 --- a/sitemap.go +++ b/sitemap.go @@ -1,10 +1,11 @@ package main import ( - "database/sql" "encoding/xml" + "fmt" "io" "net/http" + "path" "time" "github.com/araddon/dateparse" @@ -117,6 +118,12 @@ func (a *goBlog) serveSitemapBlogArchives(w http.ResponseWriter, r *http.Request sm.Add(&sitemap.URL{ Loc: a.getFullAddress(bc.getRelativePath(section.Name)), }) + datePaths, _ := a.sitemapDatePaths(b, []string{section.Name}) + for _, p := range datePaths { + sm.Add(&sitemap.URL{ + Loc: a.getFullAddress(bc.getRelativePath(path.Join(section.Name, p))), + }) + } } } // Taxonomies @@ -138,7 +145,7 @@ func (a *goBlog) serveSitemapBlogArchives(w http.ResponseWriter, r *http.Request } } // Date based archives - datePaths, _ := a.sitemapDatePaths(b) + datePaths, _ := a.sitemapDatePaths(b, []string{}) for _, p := range datePaths { sm.Add(&sitemap.URL{ Loc: a.getFullAddress(bc.getRelativePath(p)), @@ -187,15 +194,16 @@ func (a *goBlog) writeSitemapXML(w http.ResponseWriter, _ *http.Request, sm any) } const sitemapDatePathsSql = ` -with alldates as ( +with filteredposts as ( %s ), +alldates as ( select distinct substr(published, 1, 4) as year, substr(published, 6, 2) as month, substr(published, 9, 2) as day from ( - select tolocal(coalesce(published, '')) as published - from posts - where blog = @blog and status = @status and published != '' + select tolocal(published) as published + from filteredposts + where coalesce(published, '') != '' ) ) select distinct '/' || year from alldates @@ -211,8 +219,14 @@ union select distinct '/x/x/' || day from alldates; ` -func (a *goBlog) sitemapDatePaths(blog string) (paths []string, err error) { - rows, err := a.db.Query(sitemapDatePathsSql, sql.Named("blog", blog), sql.Named("status", statusPublished)) +func (a *goBlog) sitemapDatePaths(blog string, sections []string) (paths []string, err error) { + query, args := buildPostsQuery(&postsRequestConfig{ + blog: blog, + sections: sections, + status: []postStatus{statusPublished}, + visibility: []postVisibility{visibilityPublic}, + }, "published") + rows, err := a.db.Query(fmt.Sprintf(sitemapDatePathsSql, query), args...) if err != nil { return nil, err }