1
1

feed.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package main
  2. import (
  3. "encoding/xml"
  4. "net/http"
  5. "time"
  6. )
  7. const feedItems = 20
  8. type rss struct {
  9. XMLName xml.Name `xml:"rss"`
  10. Version string `xml:"version,attr"`
  11. Channel rssChannel `xml:"channel"`
  12. }
  13. type rssChannel struct {
  14. Title string `xml:"title"`
  15. Link string `xml:"link"`
  16. Description string `xml:"description"`
  17. LastBuildDate string `xml:"lastBuildDate,omitempty"`
  18. Items []rssItem `xml:"item"`
  19. }
  20. type rssItem struct {
  21. Title string `xml:"title"`
  22. Link string `xml:"link"`
  23. GUID string `xml:"guid"`
  24. PubDate string `xml:"pubDate"`
  25. Description string `xml:"description,omitempty"`
  26. }
  27. func (a *app) feed(w http.ResponseWriter, r *http.Request) {
  28. idx, err := a.store.Index()
  29. if err != nil {
  30. a.serverError(w, err)
  31. return
  32. }
  33. ch := rssChannel{
  34. Title: a.siteName,
  35. Link: a.siteURL + "/",
  36. Description: "Posts from " + a.siteName,
  37. }
  38. for i, p := range idx.posts {
  39. if i == feedItems {
  40. break
  41. }
  42. if i == 0 {
  43. ch.LastBuildDate = p.Date.Format(time.RFC1123Z)
  44. }
  45. link := a.siteURL + "/posts/" + p.Slug
  46. ch.Items = append(ch.Items, rssItem{
  47. Title: p.Title,
  48. Link: link,
  49. GUID: link,
  50. PubDate: p.Date.Format(time.RFC1123Z),
  51. Description: p.Summary,
  52. })
  53. }
  54. out, err := xml.MarshalIndent(rss{Version: "2.0", Channel: ch}, "", " ")
  55. if err != nil {
  56. a.serverError(w, err)
  57. return
  58. }
  59. w.Header().Set("Content-Type", "application/rss+xml; charset=utf-8")
  60. w.Write([]byte(xml.Header))
  61. w.Write(out)
  62. }