all repos — vite @ 71bec3e96b175b5960f518aefae0faae433af030

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

atom/feed.go (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
package atom

import (
	"encoding/xml"
	"fmt"
	"path/filepath"
	"time"

	"git.icyphox.sh/vite/config"
	"git.icyphox.sh/vite/markdown"
)

type AtomLink struct {
	XMLName xml.Name `xml:"link"`
	Href    string   `xml:"href,attr"`
	Rel     string   `xml:"rel,attr,omitempty"`
}

type AtomSummary struct {
	XMLName xml.Name `xml:"summary"`
	Content string   `xml:",chardata"`
	Type    string   `xml:"type,attr"`
}

type AtomAuthor struct {
	XMLName xml.Name `xml:"author"`
	Name    string   `xml:"name"`
	Email   string   `xml:"email"`
}

type AtomEntry struct {
	XMLName xml.Name `xml:"entry"`
	Title   string   `xml:"title"`
	Updated string   `xml:"updated"`
	ID      string   `xml:"id"`
	Link    *AtomLink
	Summary *AtomSummary
}

type AtomFeed struct {
	XMLName  xml.Name `xml:"feed"`
	Xmlns    string   `xml:"xmlns,attr"`
	Title    string   `xml:"title"`
	Subtitle string   `xml:"subtitle"`
	ID       string   `xml:"id"`
	Updated  string   `xml:"updated"`
	Link     *AtomLink
	Author   *AtomAuthor `xml:"author"`
	Entries  []AtomEntry
}

// Creates a new Atom feed.
func NewAtomFeed(srcDir string, posts []markdown.Output) ([]byte, error) {
	entries := []AtomEntry{}

	for _, p := range posts {
		dateStr := p.Meta["date"]
		date, err := time.Parse("2006-01-02", dateStr)
		if err != nil {
			return nil, err
		}
		rfc3339 := date.Format(time.RFC3339)

		entry := AtomEntry{
			Title:   p.Meta["title"],
			Updated: rfc3339,
			// tag:icyphox.sh,2019-10-23:blog/some-post/
			ID: fmt.Sprintf(
				"tag:%s,%s:%s",
				config.Config.URL[8:], // strip https://
				dateStr,
				filepath.Join(srcDir, p.Meta["slug"]),
			),
			// filepath.Join strips the second / in http://
			Link: &AtomLink{Href: config.Config.URL + filepath.Join(srcDir, p.Meta["slug"])},
			Summary: &AtomSummary{
				Content: fmt.Sprintf("<h2>%s</h2>\n%s",
					p.Meta["subtitle"],
					string(p.HTML)),
				Type: "html",
			},
		}
		entries = append(entries, entry)
	}

	// 2021-07-14T00:00:00Z
	now := time.Now().Format(time.RFC3339)
	feed := &AtomFeed{
		Xmlns:    "http://www.w3.org/2005/Atom",
		Title:    config.Config.Title,
		ID:       config.Config.URL,
		Subtitle: config.Config.Desc,
		Link:     &AtomLink{Href: config.Config.URL},
		Author: &AtomAuthor{
			Name:  config.Config.Author.Name,
			Email: config.Config.Author.Email,
		},
		Updated: now,
		Entries: entries,
	}

	feedXML, err := xml.MarshalIndent(feed, " ", " ")
	if err != nil {
		return nil, err
	}
	// Add the <?xml...> header.
	return []byte(xml.Header + string(feedXML)), nil
}