diff --git a/atom.go b/atom.go index 93cf15f..73de995 100644 --- a/atom.go +++ b/atom.go @@ -89,13 +89,16 @@ type Atom struct { func newAtomEntry(i *Item) *AtomEntry { id := i.Id - + link := i.Link + if link == nil { + link = &Link{} + } if len(id) == 0 { // if there's no id set, try to create one, either from data or just a uuid - if len(i.Link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) { + if len(link.Href) > 0 && (!i.Created.IsZero() || !i.Updated.IsZero()) { dateStr := anyTimeFormat("2006-01-02", i.Updated, i.Created) - host, path := i.Link.Href, "/invalid.html" - if url, err := url.Parse(i.Link.Href); err == nil { + host, path := link.Href, "/invalid.html" + if url, err := url.Parse(link.Href); err == nil { host, path = url.Host, url.Path } id = fmt.Sprintf("tag:%s,%s:%s", host, dateStr, path) @@ -108,13 +111,13 @@ func newAtomEntry(i *Item) *AtomEntry { name, email = i.Author.Name, i.Author.Email } - link_rel := i.Link.Rel + link_rel := link.Rel if link_rel == "" { link_rel = "alternate" } x := &AtomEntry{ Title: i.Title, - Links: []AtomLink{{Href: i.Link.Href, Rel: link_rel, Type: i.Link.Type}}, + Links: []AtomLink{{Href: link.Href, Rel: link_rel, Type: link.Type}}, Id: id, Updated: anyTimeFormat(time.RFC3339, i.Updated, i.Created), } @@ -142,12 +145,16 @@ func newAtomEntry(i *Item) *AtomEntry { // create a new AtomFeed with a generic Feed struct's data func (a *Atom) AtomFeed() *AtomFeed { updated := anyTimeFormat(time.RFC3339, a.Updated, a.Created) + link := a.Link + if link == nil { + link = &Link{} + } feed := &AtomFeed{ Xmlns: ns, Title: a.Title, - Link: &AtomLink{Href: a.Link.Href, Rel: a.Link.Rel}, + Link: &AtomLink{Href: link.Href, Rel: link.Rel}, Subtitle: a.Description, - Id: a.Link.Href, + Id: link.Href, Updated: updated, Rights: a.Copyright, } diff --git a/feed_test.go b/feed_test.go index 1c178d8..2a37f2a 100644 --- a/feed_test.go +++ b/feed_test.go @@ -504,6 +504,58 @@ func TestFeedSorted(t *testing.T) { } } +func TestFeedNil(t *testing.T) { + now, err := time.Parse(time.RFC3339, "2013-01-16T21:52:35-05:00") + if err != nil { + t.Error(err) + } + tz := time.FixedZone("EST", -5*60*60) + now = now.In(tz) + + feed := &Feed{ + Title: "jmoiron.net blog", + Link: nil, + Description: "discussion about tech, footie, photos", + Author: nil, + Created: now, + Copyright: "This work is copyright © Benjamin Button", + } + + feed.Items = []*Item{ + { + Title: "Limiting Concurrency in Go", + Link: nil, + Description: "A discussion on controlled parallelism in golang", + Author: nil, + Created: now, + Content: `

Go's goroutines make it easy to make embarrassingly parallel programs, but in many "real world" cases resources can be limited and attempting to do everything at once can exhaust your access to them.

`, + }} + + if _, err := feed.ToAtom(); err != nil { + t.Errorf("unexpected error encoding Atom: %v", err) + } + var buf bytes.Buffer + if err := feed.WriteAtom(&buf); err != nil { + t.Errorf("unexpected error writing Atom: %v", err) + } + + if _, err := feed.ToRss(); err != nil { + t.Errorf("unexpected error encoding RSS: %v", err) + } + buf.Reset() + if err := feed.WriteRss(&buf); err != nil { + t.Errorf("unexpected error writing RSS: %v", err) + } + + if _, err := feed.ToJSON(); err != nil { + t.Errorf("unexpected error encoding JSON: %v", err) + } + buf.Reset() + if err := feed.WriteJSON(&buf); err != nil { + t.Errorf("unexpected error writing JSON: %v", err) + } +} + var jsonOutputHub = `{ "version": "https://jsonfeed.org/version/1", "title": "feed title", diff --git a/rss.go b/rss.go index d05da19..8c227a8 100644 --- a/rss.go +++ b/rss.go @@ -137,9 +137,13 @@ func (r *Rss) RssFeed() *RssFeed { image = &RssImage{Url: r.Image.Url, Title: r.Image.Title, Link: r.Image.Link, Width: r.Image.Width, Height: r.Image.Height} } + var href string + if r.Link != nil { + href = r.Link.Href + } channel := &RssFeed{ Title: r.Title, - Link: r.Link.Href, + Link: href, Description: r.Description, ManagingEditor: author, PubDate: pub,