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