all repos — vite @ fbcc6c93a3aa3282d34c7c90a223c9535e8d2b94

a fast (this time, actually) and minimal static site generator

atom/feed.go (view raw)

  1package atom
  2
  3import (
  4	"encoding/xml"
  5	"fmt"
  6	"path/filepath"
  7	"time"
  8
  9	"git.icyphox.sh/vite/config"
 10	"git.icyphox.sh/vite/markdown"
 11)
 12
 13type AtomLink struct {
 14	XMLName xml.Name `xml:"link"`
 15	Href    string   `xml:"href,attr"`
 16	Rel     string   `xml:"rel,attr,omitempty"`
 17}
 18
 19type AtomSummary struct {
 20	XMLName xml.Name `xml:"summary"`
 21	Content string   `xml:",chardata"`
 22	Type    string   `xml:"type,attr"`
 23}
 24
 25type AtomAuthor struct {
 26	XMLName xml.Name `xml:"author"`
 27	Name    string   `xml:"name"`
 28	Email   string   `xml:"email"`
 29}
 30
 31type AtomEntry struct {
 32	XMLName xml.Name `xml:"entry"`
 33	Title   string   `xml:"title"`
 34	Updated string   `xml:"updated"`
 35	ID      string   `xml:"id"`
 36	Link    *AtomLink
 37	Summary *AtomSummary
 38}
 39
 40type AtomFeed struct {
 41	XMLName  xml.Name `xml:"feed"`
 42	Xmlns    string   `xml:"xmlns,attr"`
 43	Title    string   `xml:"title"`
 44	Subtitle string   `xml:"subtitle"`
 45	ID       string   `xml:"id"`
 46	Updated  string   `xml:"updated"`
 47	Link     *AtomLink
 48	Author   *AtomAuthor `xml:"author"`
 49	Entries  []AtomEntry
 50}
 51
 52// Creates a new Atom feed.
 53func NewAtomFeed(srcDir string, posts []markdown.Output) ([]byte, error) {
 54	entries := []AtomEntry{}
 55	cfg := config.ConfigYaml{}
 56	cfg.ParseConfig()
 57	for _, p := range posts {
 58		dateStr := p.Meta["date"]
 59		date, err := time.Parse("2006-01-02", dateStr)
 60		if err != nil {
 61			return nil, err
 62		}
 63		rfc3339 := date.Format(time.RFC3339)
 64
 65		entry := AtomEntry{
 66			Title:   p.Meta["title"],
 67			Updated: rfc3339,
 68			// tag:icyphox.sh,2019-10-23:blog/some-post/
 69			ID: fmt.Sprintf(
 70				"tag:%s,%s:%s",
 71				cfg.URL[8:], // strip https://
 72				dateStr,
 73				filepath.Join(srcDir, p.Meta["slug"]),
 74			),
 75			// filepath.Join strips the second / in http://
 76			Link: &AtomLink{Href: cfg.URL + filepath.Join(srcDir, p.Meta["slug"])},
 77			Summary: &AtomSummary{
 78				Content: fmt.Sprintf("<h2>%s</h2>\n%s",
 79					p.Meta["subtitle"],
 80					string(p.HTML)),
 81				Type: "html",
 82			},
 83		}
 84		entries = append(entries, entry)
 85	}
 86
 87	// 2021-07-14T00:00:00Z
 88	now := time.Now().Format(time.RFC3339)
 89	feed := &AtomFeed{
 90		Xmlns:    "http://www.w3.org/2005/Atom",
 91		Title:    cfg.Title,
 92		ID:       cfg.URL,
 93		Subtitle: cfg.Desc,
 94		Link:     &AtomLink{Href: cfg.URL},
 95		Author: &AtomAuthor{
 96			Name:  cfg.Author.Name,
 97			Email: cfg.Author.Email,
 98		},
 99		Updated: now,
100		Entries: entries,
101	}
102
103	feedXML, err := xml.MarshalIndent(feed, " ", " ")
104	if err != nil {
105		return nil, err
106	}
107	// Add the <?xml...> header.
108	return []byte(xml.Header + string(feedXML)), nil
109}