mirror of
https://github.com/jlelse/GoBlog
synced 2024-06-08 08:26:27 +00:00
Add date-based archives per section
This commit is contained in:
parent
503b98327f
commit
a89a9cafa3
|
@ -145,7 +145,7 @@ func (a *goBlog) blogRouter(blog string, conf *configBlog) func(r chi.Router) {
|
||||||
r.Group(a.blogTaxonomiesRouter(conf))
|
r.Group(a.blogTaxonomiesRouter(conf))
|
||||||
|
|
||||||
// Dates
|
// Dates
|
||||||
r.Group(a.blogDatesRouter(conf))
|
r.With(a.privateModeHandler, a.cacheMiddleware).Group(a.blogDatesRouter(conf))
|
||||||
|
|
||||||
// Photos
|
// Photos
|
||||||
r.Group(a.blogPhotosRouter(conf))
|
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) {
|
r.Group(func(r chi.Router) {
|
||||||
secPath := conf.getRelativePath(section.Name)
|
secPath := conf.getRelativePath(section.Name)
|
||||||
r.Use(middleware.WithValue(indexConfigKey, &indexConfig{
|
r.Use(middleware.WithValue(indexConfigKey, &indexConfig{
|
||||||
path: secPath,
|
path: secPath,
|
||||||
section: section,
|
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+feedPath, a.serveIndex)
|
||||||
r.Get(secPath+paginationPath, a.serveIndex)
|
r.Get(secPath+paginationPath, a.serveIndex)
|
||||||
})
|
})
|
||||||
|
@ -246,11 +251,6 @@ func (a *goBlog) blogTaxonomiesRouter(conf *configBlog) func(r chi.Router) {
|
||||||
// Blog - Dates
|
// Blog - Dates
|
||||||
func (a *goBlog) blogDatesRouter(conf *configBlog) func(r chi.Router) {
|
func (a *goBlog) blogDatesRouter(conf *configBlog) func(r chi.Router) {
|
||||||
return func(r chi.Router) {
|
return func(r chi.Router) {
|
||||||
r.Use(
|
|
||||||
a.privateModeHandler,
|
|
||||||
a.cacheMiddleware,
|
|
||||||
)
|
|
||||||
|
|
||||||
yearPath := conf.getRelativePath(`/{year:(x|\d{4})}`)
|
yearPath := conf.getRelativePath(`/{year:(x|\d{4})}`)
|
||||||
r.Get(yearPath, a.serveDate)
|
r.Get(yearPath, a.serveDate)
|
||||||
r.Get(yearPath+feedPath, a.serveDate)
|
r.Get(yearPath+feedPath, a.serveDate)
|
||||||
|
|
81
posts.go
81
posts.go
|
@ -5,6 +5,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"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) {
|
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" {
|
if ys := chi.URLParam(r, "year"); ys != "" && ys != "x" {
|
||||||
year = stringToInt(ys)
|
year = stringToInt(ys)
|
||||||
}
|
}
|
||||||
|
@ -229,38 +255,29 @@ func (a *goBlog) serveDate(w http.ResponseWriter, r *http.Request) {
|
||||||
if ds := chi.URLParam(r, "day"); ds != "" {
|
if ds := chi.URLParam(r, "day"); ds != "" {
|
||||||
day = stringToInt(ds)
|
day = stringToInt(ds)
|
||||||
}
|
}
|
||||||
if year == 0 && month == 0 && day == 0 {
|
titleBuf, pathBuf := bufferpool.Get(), bufferpool.Get()
|
||||||
a.serve404(w, r)
|
defer bufferpool.Put(titleBuf, pathBuf)
|
||||||
return
|
|
||||||
}
|
|
||||||
title, dPath := bufferpool.Get(), bufferpool.Get()
|
|
||||||
if year != 0 {
|
if year != 0 {
|
||||||
_, _ = fmt.Fprintf(title, "%0004d", year)
|
_, _ = fmt.Fprintf(titleBuf, "%0004d", year)
|
||||||
_, _ = fmt.Fprintf(dPath, "%0004d", year)
|
_, _ = fmt.Fprintf(pathBuf, "%0004d", year)
|
||||||
} else {
|
} else {
|
||||||
_, _ = title.WriteString("XXXX")
|
_, _ = titleBuf.WriteString("XXXX")
|
||||||
_, _ = dPath.WriteString("x")
|
_, _ = pathBuf.WriteString("x")
|
||||||
}
|
}
|
||||||
if month != 0 {
|
if month != 0 {
|
||||||
_, _ = fmt.Fprintf(title, "-%02d", month)
|
_, _ = fmt.Fprintf(titleBuf, "-%02d", month)
|
||||||
_, _ = fmt.Fprintf(dPath, "/%02d", month)
|
_, _ = fmt.Fprintf(pathBuf, "/%02d", month)
|
||||||
} else if day != 0 {
|
} else if day != 0 {
|
||||||
_, _ = title.WriteString("-XX")
|
_, _ = titleBuf.WriteString("-XX")
|
||||||
_, _ = dPath.WriteString("/x")
|
_, _ = pathBuf.WriteString("/x")
|
||||||
}
|
}
|
||||||
if day != 0 {
|
if day != 0 {
|
||||||
_, _ = fmt.Fprintf(title, "-%02d", day)
|
_, _ = fmt.Fprintf(titleBuf, "-%02d", day)
|
||||||
_, _ = fmt.Fprintf(dPath, "/%02d", day)
|
_, _ = fmt.Fprintf(pathBuf, "/%02d", day)
|
||||||
}
|
}
|
||||||
_, bc := a.getBlog(r)
|
title = titleBuf.String()
|
||||||
a.serveIndex(w, r.WithContext(context.WithValue(r.Context(), indexConfigKey, &indexConfig{
|
datePath = pathBuf.String()
|
||||||
path: bc.getRelativePath(dPath.String()),
|
return
|
||||||
year: year,
|
|
||||||
month: month,
|
|
||||||
day: day,
|
|
||||||
title: title.String(),
|
|
||||||
})))
|
|
||||||
bufferpool.Put(title, dPath)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type indexConfig struct {
|
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)
|
a.serveError(w, r, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Meta
|
// Title
|
||||||
title := ic.title
|
var title string
|
||||||
description := ic.description
|
if ic.title != "" {
|
||||||
if ic.tax != nil {
|
title = ic.title
|
||||||
|
} else if ic.tax != nil {
|
||||||
title = fmt.Sprintf("%s: %s", ic.tax.Title, ic.taxValue)
|
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 != "" {
|
} else if search != "" {
|
||||||
title = fmt.Sprintf("%s: %s", bc.Search.Title, search)
|
title = fmt.Sprintf("%s: %s", bc.Search.Title, search)
|
||||||
}
|
}
|
||||||
|
// Description
|
||||||
|
description := ic.description
|
||||||
// Check if feed
|
// Check if feed
|
||||||
if ft := feedType(chi.URLParam(r, "feed")); ft != noFeed {
|
if ft := feedType(chi.URLParam(r, "feed")); ft != noFeed {
|
||||||
a.generateFeed(blog, ft, w, r, posts, title, description)
|
a.generateFeed(blog, ft, w, r, posts, title, description)
|
||||||
|
|
30
sitemap.go
30
sitemap.go
|
@ -1,10 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"path"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/araddon/dateparse"
|
"github.com/araddon/dateparse"
|
||||||
|
@ -117,6 +118,12 @@ func (a *goBlog) serveSitemapBlogArchives(w http.ResponseWriter, r *http.Request
|
||||||
sm.Add(&sitemap.URL{
|
sm.Add(&sitemap.URL{
|
||||||
Loc: a.getFullAddress(bc.getRelativePath(section.Name)),
|
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
|
// Taxonomies
|
||||||
|
@ -138,7 +145,7 @@ func (a *goBlog) serveSitemapBlogArchives(w http.ResponseWriter, r *http.Request
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Date based archives
|
// Date based archives
|
||||||
datePaths, _ := a.sitemapDatePaths(b)
|
datePaths, _ := a.sitemapDatePaths(b, []string{})
|
||||||
for _, p := range datePaths {
|
for _, p := range datePaths {
|
||||||
sm.Add(&sitemap.URL{
|
sm.Add(&sitemap.URL{
|
||||||
Loc: a.getFullAddress(bc.getRelativePath(p)),
|
Loc: a.getFullAddress(bc.getRelativePath(p)),
|
||||||
|
@ -187,15 +194,16 @@ func (a *goBlog) writeSitemapXML(w http.ResponseWriter, _ *http.Request, sm any)
|
||||||
}
|
}
|
||||||
|
|
||||||
const sitemapDatePathsSql = `
|
const sitemapDatePathsSql = `
|
||||||
with alldates as (
|
with filteredposts as ( %s ),
|
||||||
|
alldates as (
|
||||||
select distinct
|
select distinct
|
||||||
substr(published, 1, 4) as year,
|
substr(published, 1, 4) as year,
|
||||||
substr(published, 6, 2) as month,
|
substr(published, 6, 2) as month,
|
||||||
substr(published, 9, 2) as day
|
substr(published, 9, 2) as day
|
||||||
from (
|
from (
|
||||||
select tolocal(coalesce(published, '')) as published
|
select tolocal(published) as published
|
||||||
from posts
|
from filteredposts
|
||||||
where blog = @blog and status = @status and published != ''
|
where coalesce(published, '') != ''
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
select distinct '/' || year from alldates
|
select distinct '/' || year from alldates
|
||||||
|
@ -211,8 +219,14 @@ union
|
||||||
select distinct '/x/x/' || day from alldates;
|
select distinct '/x/x/' || day from alldates;
|
||||||
`
|
`
|
||||||
|
|
||||||
func (a *goBlog) sitemapDatePaths(blog string) (paths []string, err error) {
|
func (a *goBlog) sitemapDatePaths(blog string, sections []string) (paths []string, err error) {
|
||||||
rows, err := a.db.Query(sitemapDatePathsSql, sql.Named("blog", blog), sql.Named("status", statusPublished))
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user