feat(generator): add RSS 2.0 and Atom feed generation (#80)#81
Merged
Conversation
Feeds are generated automatically when a base URL is configured via WithBaseURL. Without a base URL the build succeeds and emits an info log rather than failing. Features: - Site-wide rss.xml and atom.xml at the output root - Per-tag <tag>.rss.xml and <tag>.atom.xml under tags/ - Full post HTML content in every feed item - Post URL used as the item's unique identifier (guid/id) - Configurable post limit (default 10, newest-first) - WithDisableFeeds() to opt out entirely - FeedsEnabled flag on BaseData controls template discovery links and visible RSS nav link in the default theme - New config options: WithBaseURL, WithDisableFeeds, WithFeedPostLimit - CLI flags: --base-url, --disable-feeds, --feed-limit Uses github.com/gorilla/feeds for RSS/Atom serialisation. Closes #80
Feed logic now lives as unexported methods on *Generator, pulling limit, title, base URL, and blog root directly from the receiver rather than requiring callers to pass them explicitly. AbsURL remains exported as a standalone utility. Call sites in assembleBlogWithTemplates simplify to g.buildFeeds(posts) and g.buildFeedsWithTitle(posts, title).
…thods Replace buildFeedsWithTitle(posts, title) with two intent-named methods: buildFeeds for the site-wide feed and buildTagFeeds(tag, posts) for per-tag feeds. Both derive the feed title from the generator's own SiteTitle, removing a parameter that duplicated information already available on the receiver.
The feed-level <updated> (Atom) and <lastBuildDate> (RSS) were always set to posts[0].Date — the newest post's publication date. Per RFC 4287 §4.2.15 the feed's <updated> must reflect the most recent instant any entry was significantly modified. Editing an older post without publishing a new one left the timestamp unchanged, so aggregators and caches could miss the edit entirely. Fix computes the maximum effective-updated time across all windowed posts (LastEdited if set, otherwise Date) and uses that for feed.Updated; feed.Created remains posts[0].Date. Per-item timestamps were already correct and are unchanged. Adds three tests for the previously zero-coverage LastEdited paths: feed-level updated reflects an edit, item Atom <updated> reflects LastEdited, and regression guard when no edits are present.
- Rename AbsURL → absURL; it has no external consumers and is an internal helper for feed URL construction. - Set --feed-limit flag default to 10 (matching the generator's internal default) so the CLI help text displays the correct value rather than 0. - Remove dead code in TestGenerator_FeedPostLimit: an abandoned postTemplate const and postsMap loop that were superseded by an inline fstest.MapFS but never deleted.
…serve
Move template-dir, root-path, disable-tags, disable-reading-time,
base-url, disable-feeds, and feed-limit from per-subcommand flag
definitions to the top-level goblog command via a new internal/cliflags
package. urfave/cli v3 persists root flags to all subcommands, so both
generate and serve share one canonical definition with no duplication.
Wire the three feed options (base-url, disable-feeds, feed-limit) into
the serve command's generator config so the embedded generator produces
RSS/Atom content. Extend pkg/server/handler to expose that content at
{root}rss.xml, {root}atom.xml, and {root}tags/{tag}.{rss,atom}.xml,
matching the static file layout written by pkg/outputter. Feed routes
return 404 when no base-url is configured.
Remove the library-side 0→10 coercion in generator.New so that WithFeedPostLimit(0) (and the unset default) now means unlimited. The 10-post default is retained in the CLI flag value; both generate and serve subcommands now pass the flag value unconditionally. Clarify in godoc and README that WithBaseURL must be scheme+host only — combining a path here with WithBlogRoot produces doubled segments in every feed URL. Also extract effectiveUpdated() helper to deduplicate the LastEdited-vs-Date logic, expand the handleTag comment to explain why feed demuxing lives inside the wildcard handler, and fix a stale AbsURL→absURL error message in the test.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Feeds are generated automatically when a base URL is configured via WithBaseURL. Without a base URL the build succeeds and emits an info log rather than failing. Features:
Uses github.com/gorilla/feeds for RSS/Atom serialisation.
Closes #80
Changelog (#81)
✨ New Features
🐛 Bug Fixes
♻️ Refactoring