dir: Combine handling of feeds and deprecated feeds

This commit is contained in:
adnano 2021-09-03 00:22:07 -04:00
parent bad156cad3
commit d300bc23c0
3 changed files with 69 additions and 67 deletions

107
dir.go
View file

@ -18,13 +18,12 @@ import (
// Dir represents a directory. // Dir represents a directory.
type Dir struct { type Dir struct {
Permalink string Permalink string
Pages []*Page Pages []*Page
Dirs []*Dir Dirs []*Dir
index *Page // The index page. index *Page // The index page.
feed []byte // Atom feed (deprecated) feeds map[string][]byte // Atom/RSS/Custom feeds.
extraFiles map[string][]byte // Atom/RSS feeds path string // relative to the content dir
path string // relative to the content dir
} }
// Page represents a page. // Page represents a page.
@ -159,7 +158,7 @@ func (d *Dir) process(cfg *Site, task *Task) error {
if err != nil { if err != nil {
return err return err
} }
d.addExtraFile(feed.Output, b) d.addFeed(feed.Output, b)
} }
if task.TemplateExt != "" { if task.TemplateExt != "" {
@ -188,34 +187,6 @@ func (d *Dir) process(cfg *Site, task *Task) error {
} }
} }
// Feed represents a feed.
type Feed struct {
Title string // Feed title.
Permalink string // Feed permalink.
Updated time.Time // Last updated time.
Entries []*Page // Feed entries.
}
// Create feeds
if title, ok := cfg.Feeds[d.Permalink]; ok {
var b bytes.Buffer
feed := &Feed{
Title: title,
Permalink: d.Permalink,
Updated: time.Now(),
Entries: d.Pages,
}
tmpl, ok := cfg.templates.FindTemplate(d.Permalink, "atom.xml")
if ok {
if err := tmpl.Execute(&b, feed); err != nil {
return err
}
d.feed = b.Bytes()
} else {
fmt.Printf("Warning: failed to generate feed %q: missing template \"atom.xml\"\n", title)
}
}
// Process subdirectories // Process subdirectories
for _, d := range d.Dirs { for _, d := range d.Dirs {
if err := d.process(cfg, task); err != nil { if err := d.process(cfg, task); err != nil {
@ -227,22 +198,43 @@ func (d *Dir) process(cfg *Site, task *Task) error {
// buildFeed build the feed of the directory // buildFeed build the feed of the directory
func (d Dir) buildFeed(cfg *Site, feed Feed) ([]byte, error) { func (d Dir) buildFeed(cfg *Site, feed Feed) ([]byte, error) {
// Feed represents a feed.
type Feed struct {
Title string
Permalink string
Updated time.Time
Pages []*Page
}
// DeprecatedFeed represents a deprecated feed.
type DeprecatedFeed struct {
Title string
Permalink string
Updated time.Time
Entries []*Page
}
tmpl, ok := cfg.templates.FindTemplate(d.Permalink, feed.Template) tmpl, ok := cfg.templates.FindTemplate(d.Permalink, feed.Template)
if !ok { if !ok {
return nil, fmt.Errorf("missing feed template %q to generate %q", feed.Template, feed.Title) return nil, fmt.Errorf("failed to generate feed %q: missing feed template %q", feed.Title, feed.Template)
} }
var b bytes.Buffer var b bytes.Buffer
data := struct { var data interface{}
Title string // Feed title. if !feed.deprecated {
Permalink string // Feed permalink. data = Feed{
Updated time.Time // Last updated time. Title: feed.Title,
Pages []*Page // Feed pages. Permalink: d.Permalink,
}{ Updated: time.Now(),
Title: feed.Title, Pages: d.Pages,
Permalink: d.Permalink, }
Updated: time.Now(), } else {
Pages: d.Pages, data = DeprecatedFeed{
Title: feed.Title,
Permalink: d.Permalink,
Updated: time.Now(),
Entries: d.Pages,
}
} }
if err := tmpl.Execute(&b, data); err != nil { if err := tmpl.Execute(&b, data); err != nil {
return nil, err return nil, err
@ -250,12 +242,11 @@ func (d Dir) buildFeed(cfg *Site, feed Feed) ([]byte, error) {
return b.Bytes(), nil return b.Bytes(), nil
} }
func (d *Dir) addExtraFile(name string, content []byte) { func (d *Dir) addFeed(name string, content []byte) {
if d.extraFiles == nil { if d.feeds == nil {
d.extraFiles = map[string][]byte{name: content} d.feeds = map[string][]byte{}
} else {
d.extraFiles[name] = content
} }
d.feeds[name] = content
} }
// write writes the directory's contents to the provided destination path. // write writes the directory's contents to the provided destination path.
@ -289,18 +280,8 @@ func (d *Dir) write(dstDir string, task *Task) error {
} }
} }
// Write the atom feed
if d.feed != nil {
const path = "atom.xml"
dstPath := pathpkg.Join(dirPath, path)
os.MkdirAll(dirPath, 0755)
if err := os.WriteFile(dstPath, d.feed, 0644); err != nil {
return err
}
}
// Write feeds // Write feeds
for name, content := range d.extraFiles { for name, content := range d.feeds {
dstPath := pathpkg.Join(dstDir, name) dstPath := pathpkg.Join(dstDir, name)
os.MkdirAll(dirPath, 0755) os.MkdirAll(dirPath, 0755)
if err := os.WriteFile(dstPath, content, 0644); err != nil { if err := os.WriteFile(dstPath, content, 0644); err != nil {

View file

@ -51,11 +51,11 @@ func build() {
site, err := LoadSite(config) site, err := LoadSite(config)
if err != nil { if err != nil {
log.Fatal(err) log.Fatalf("ERROR: %v", err)
} }
if err := site.run(); err != nil { if err := site.run(); err != nil {
log.Fatal(err) log.Fatalf("ERROR: %v", err)
} }
} }

25
site.go
View file

@ -16,7 +16,7 @@ type Site struct {
Title string `toml:"title"` Title string `toml:"title"`
URLs []string `toml:"urls"` URLs []string `toml:"urls"`
Tasks []*Task `toml:"tasks"` Tasks []*Task `toml:"tasks"`
Feeds map[string]string `toml:"feeds"` Feeds map[string]string `toml:"feeds"` // Deprecated. Use Task.Feeds instead
Params map[string]string `toml:"params"` Params map[string]string `toml:"params"`
Permalinks map[string]string `toml:"permalinks"` Permalinks map[string]string `toml:"permalinks"`
permalinks map[string]*template.Template permalinks map[string]*template.Template
@ -43,6 +43,9 @@ type Feed struct {
Title string `toml:"title"` Title string `toml:"title"`
Template string `toml:"template"` Template string `toml:"template"`
Output string `toml:"output"` Output string `toml:"output"`
// if true, the feed was specified using deprecated configuration options.
deprecated bool
} }
func (t *Task) Match(ext string) bool { func (t *Task) Match(ext string) bool {
@ -96,7 +99,25 @@ func LoadSite(config string) (*Site, error) {
for _, task := range site.Tasks { for _, task := range site.Tasks {
task.feeds = map[string][]Feed{} task.feeds = map[string][]Feed{}
for _, feed := range task.Feeds { for _, feed := range task.Feeds {
task.feeds[feed.InputDir] = append(task.feeds[feed.InputDir], feed) dir := feed.InputDir
task.feeds[dir] = append(task.feeds[dir], feed)
}
}
// Populate task feeds map with deprecated feeds
for dir, title := range site.Feeds {
// Deprecated feeds apply to every task
for _, task := range site.Tasks {
if _, ok := task.feeds[dir]; !ok {
dir = strings.TrimSuffix(dir, "/")
task.feeds[dir] = append(task.feeds[dir], Feed{
InputDir: dir,
Title: title,
Template: "atom.xml",
Output: path.Join(dir, "atom.xml"),
deprecated: true,
})
}
} }
} }