Bring back the RSS/Atom feeds
This commit is contained in:
parent
9f25d38276
commit
0ca2ebd874
|
@ -185,6 +185,7 @@ func (b *Blog) SettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
mailPort, _ := strconv.Atoi(r.FormValue("mail-port"))
|
mailPort, _ := strconv.Atoi(r.FormValue("mail-port"))
|
||||||
form := &forms.Settings{
|
form := &forms.Settings{
|
||||||
Title: r.FormValue("title"),
|
Title: r.FormValue("title"),
|
||||||
|
Description: r.FormValue("description"),
|
||||||
AdminEmail: r.FormValue("admin-email"),
|
AdminEmail: r.FormValue("admin-email"),
|
||||||
URL: r.FormValue("url"),
|
URL: r.FormValue("url"),
|
||||||
RedisEnabled: len(r.FormValue("redis-enabled")) > 0,
|
RedisEnabled: len(r.FormValue("redis-enabled")) > 0,
|
||||||
|
@ -203,6 +204,7 @@ func (b *Blog) SettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// Copy form values into the settings struct for display, in case of
|
// Copy form values into the settings struct for display, in case of
|
||||||
// any validation errors.
|
// any validation errors.
|
||||||
settings.Site.Title = form.Title
|
settings.Site.Title = form.Title
|
||||||
|
settings.Site.Description = form.Description
|
||||||
settings.Site.AdminEmail = form.AdminEmail
|
settings.Site.AdminEmail = form.AdminEmail
|
||||||
settings.Site.URL = form.URL
|
settings.Site.URL = form.URL
|
||||||
settings.Redis.Enabled = form.RedisEnabled
|
settings.Redis.Enabled = form.RedisEnabled
|
||||||
|
|
63
core/blog.go
63
core/blog.go
|
@ -11,9 +11,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/feeds"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/kirsle/blog/core/models/comments"
|
"github.com/kirsle/blog/core/models/comments"
|
||||||
"github.com/kirsle/blog/core/models/posts"
|
"github.com/kirsle/blog/core/models/posts"
|
||||||
|
"github.com/kirsle/blog/core/models/settings"
|
||||||
"github.com/kirsle/blog/core/models/users"
|
"github.com/kirsle/blog/core/models/users"
|
||||||
"github.com/urfave/negroni"
|
"github.com/urfave/negroni"
|
||||||
)
|
)
|
||||||
|
@ -39,6 +41,8 @@ type Archive struct {
|
||||||
func (b *Blog) BlogRoutes(r *mux.Router) {
|
func (b *Blog) BlogRoutes(r *mux.Router) {
|
||||||
// Public routes
|
// Public routes
|
||||||
r.HandleFunc("/blog", b.IndexHandler)
|
r.HandleFunc("/blog", b.IndexHandler)
|
||||||
|
r.HandleFunc("/blog.rss", b.RSSHandler)
|
||||||
|
r.HandleFunc("/blog.atom", b.RSSHandler)
|
||||||
r.HandleFunc("/archive", b.BlogArchive)
|
r.HandleFunc("/archive", b.BlogArchive)
|
||||||
r.HandleFunc("/tagged", b.Tagged)
|
r.HandleFunc("/tagged", b.Tagged)
|
||||||
r.HandleFunc("/tagged/{tag}", b.Tagged)
|
r.HandleFunc("/tagged/{tag}", b.Tagged)
|
||||||
|
@ -84,6 +88,51 @@ func (b *Blog) BlogRoutes(r *mux.Router) {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RSSHandler renders an RSS feed from the blog.
|
||||||
|
func (b *Blog) RSSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
config, _ := settings.Load()
|
||||||
|
admin, err := users.Load(1)
|
||||||
|
if err != nil {
|
||||||
|
b.Error(w, r, "Blog isn't ready yet.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
feed := &feeds.Feed{
|
||||||
|
Title: config.Site.Title,
|
||||||
|
Link: &feeds.Link{Href: config.Site.URL},
|
||||||
|
Description: config.Site.Description,
|
||||||
|
Author: &feeds.Author{
|
||||||
|
Name: admin.Name,
|
||||||
|
Email: admin.Email,
|
||||||
|
},
|
||||||
|
Created: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
feed.Items = []*feeds.Item{}
|
||||||
|
for i, p := range b.RecentPosts(r, "", "") {
|
||||||
|
feed.Items = append(feed.Items, &feeds.Item{
|
||||||
|
Title: p.Title,
|
||||||
|
Link: &feeds.Link{Href: config.Site.URL + p.Fragment},
|
||||||
|
Description: strings.Split(p.Body, "<snip>")[0],
|
||||||
|
Created: p.Created,
|
||||||
|
})
|
||||||
|
if i >= 5 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// What format to encode it in?
|
||||||
|
if strings.Contains(r.URL.Path, ".atom") {
|
||||||
|
atom, _ := feed.ToAtom()
|
||||||
|
w.Header().Set("Content-Type", "application/atom+xml")
|
||||||
|
w.Write([]byte(atom))
|
||||||
|
} else {
|
||||||
|
rss, _ := feed.ToRss()
|
||||||
|
w.Header().Set("Content-Type", "application/rss+xml")
|
||||||
|
w.Write([]byte(rss))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// IndexHandler renders the main index page of the blog.
|
// IndexHandler renders the main index page of the blog.
|
||||||
func (b *Blog) IndexHandler(w http.ResponseWriter, r *http.Request) {
|
func (b *Blog) IndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
b.CommonIndexHandler(w, r, "", "")
|
b.CommonIndexHandler(w, r, "", "")
|
||||||
|
@ -133,8 +182,8 @@ func (b *Blog) CommonIndexHandler(w http.ResponseWriter, r *http.Request, tag, p
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderIndex renders and returns the blog index partial.
|
// RecentPosts gets and filters the blog entries and orders them by most recent.
|
||||||
func (b *Blog) RenderIndex(r *http.Request, tag, privacy string) template.HTML {
|
func (b *Blog) RecentPosts(r *http.Request, tag, privacy string) []posts.Post {
|
||||||
// Get the blog index.
|
// Get the blog index.
|
||||||
idx, _ := posts.GetIndex()
|
idx, _ := posts.GetIndex()
|
||||||
|
|
||||||
|
@ -182,12 +231,18 @@ func (b *Blog) RenderIndex(r *http.Request, tag, privacy string) template.HTML {
|
||||||
pool = append(pool, post)
|
pool = append(pool, post)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sort.Sort(sort.Reverse(posts.ByUpdated(pool)))
|
||||||
|
return pool
|
||||||
|
}
|
||||||
|
|
||||||
|
// RenderIndex renders and returns the blog index partial.
|
||||||
|
func (b *Blog) RenderIndex(r *http.Request, tag, privacy string) template.HTML {
|
||||||
|
// Get the recent blog entries, filtered by the tag/privacy settings.
|
||||||
|
pool := b.RecentPosts(r, tag, privacy)
|
||||||
if len(pool) == 0 {
|
if len(pool) == 0 {
|
||||||
return template.HTML("No blog posts were found.")
|
return template.HTML("No blog posts were found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(sort.Reverse(posts.ByUpdated(pool)))
|
|
||||||
|
|
||||||
// Query parameters.
|
// Query parameters.
|
||||||
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
page, _ := strconv.Atoi(r.URL.Query().Get("page"))
|
||||||
if page <= 0 {
|
if page <= 0 {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
// Settings are the user-facing admin settings.
|
// Settings are the user-facing admin settings.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Title string
|
Title string
|
||||||
|
Description string
|
||||||
AdminEmail string
|
AdminEmail string
|
||||||
URL string
|
URL string
|
||||||
RedisEnabled bool
|
RedisEnabled bool
|
||||||
|
|
|
@ -18,6 +18,7 @@ type Settings struct {
|
||||||
|
|
||||||
Site struct {
|
Site struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
|
Description string `json:"description"`
|
||||||
AdminEmail string `json:"adminEmail"`
|
AdminEmail string `json:"adminEmail"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
} `json:"site"`
|
} `json:"site"`
|
||||||
|
|
|
@ -15,6 +15,15 @@
|
||||||
placeholder="Website Title">
|
placeholder="Website Title">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">Description</label>
|
||||||
|
<input type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="description"
|
||||||
|
value="{{ .Site.Description }}"
|
||||||
|
placeholder="Just another web blog.">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="admin-email">Admin Email</label>
|
<label for="admin-email">Admin Email</label>
|
||||||
<small class="text-muted">For getting notifications about comments, etc.</small>
|
<small class="text-muted">For getting notifications about comments, etc.</small>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user