diff --git a/src/controllers/posts/feeds.go b/src/controllers/posts/feeds.go index de9ed2e..5ef5030 100644 --- a/src/controllers/posts/feeds.go +++ b/src/controllers/posts/feeds.go @@ -1,15 +1,26 @@ package postctl import ( + "fmt" "net/http" + "regexp" "strings" "time" "github.com/gorilla/feeds" - "github.com/kirsle/blog/src/responses" "github.com/kirsle/blog/models/posts" "github.com/kirsle/blog/models/settings" "github.com/kirsle/blog/models/users" + "github.com/kirsle/blog/src/markdown" + "github.com/kirsle/blog/src/responses" + "github.com/kirsle/blog/src/types" +) + +// Feed configuration. TODO make configurable. +var ( + FeedPostsPerPage = 20 + + reRelativeLink = regexp.MustCompile(` (src|href|poster)=(['"])/([^'"]+)['"]`) ) func feedHandler(w http.ResponseWriter, r *http.Request) { @@ -34,19 +45,37 @@ func feedHandler(w http.ResponseWriter, r *http.Request) { feed.Items = []*feeds.Item{} for i, p := range RecentPosts(r, "", "") { post, _ := posts.Load(p.ID) - var suffix string - if strings.Contains(post.Body, "") { - post.Body = strings.Split(post.Body, "")[0] - suffix = "..." + + // Render the post to HTML. + var rendered string + if post.ContentType == string(types.MARKDOWN) { + rendered = markdown.RenderTrustedMarkdown(post.Body) + } else { + rendered = post.Body + } + + // Make relative links absolute. + matches := reRelativeLink.FindAllStringSubmatch(rendered, -1) + for _, match := range matches { + var ( + attr = match[1] + quote = match[2] + uri = match[3] + absURI = config.Site.URL + "/" + uri + new = fmt.Sprintf(" %s%s%s%s", + attr, quote, absURI, quote, + ) + ) + rendered = strings.Replace(rendered, match[0], new, 1) } feed.Items = append(feed.Items, &feeds.Item{ Title: p.Title, Link: &feeds.Link{Href: config.Site.URL + p.Fragment}, - Description: post.Body + suffix, + Description: rendered, Created: p.Created, }) - if i == 9 { // 10 -1 + if i == FeedPostsPerPage-1 { break } } @@ -58,7 +87,7 @@ func feedHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte(atom)) } else { rss, _ := feed.ToRss() - w.Header().Set("Content-Type", "application/rss+xml") + w.Header().Set("Content-Type", "application/rss+xml; encoding=utf-8") w.Write([]byte(rss)) } } diff --git a/src/middleware/age-gate.go b/src/middleware/age-gate.go index 1a404c0..4806e24 100644 --- a/src/middleware/age-gate.go +++ b/src/middleware/age-gate.go @@ -11,6 +11,8 @@ import ( ) var ageGateSuffixes = []string{ + "/blog.rss", // Allow public access to RSS and Atom feeds. + "/blog.atom", ".js", ".css", ".txt", @@ -39,8 +41,8 @@ func AgeGate(verifyHandler func(http.ResponseWriter, *http.Request)) negroni.Han } // Allow static files and things through. - for _, prefix := range ageGateSuffixes { - if strings.HasSuffix(path, prefix) { + for _, suffix := range ageGateSuffixes { + if strings.HasSuffix(path, suffix) { next(w, r) return }