flexweg-rss
The flexweg-rss plugin generates RSS 2.0 feeds for your public site — one site-wide feed and as many per-category feeds as you want. Items are sorted newest-first; each carries title, description, link, pubDate, author, and an optional enclosure for the hero image.
What it generates
| Feed | Path on Flexweg | Default item count |
|---|---|---|
| Site-wide | /rss.xml | 20 |
| Per category | /<category-slug>/<category-slug>.xml | 20 (configurable per feed) |
| Stylesheet | /rss.xml.xsl | (one, shared) |
Per-category feeds use a doubled slug (/news/news.xml rather than /news/index.xml) so the file doesn't collide with the category archive HTML at /news/index.html.
The XSL stylesheet renders feeds as a styled HTML table when opened directly in a browser — RSS readers ignore the <?xml-stylesheet?> PI and parse the XML normally.
Settings
/settings/plugin/flexweg-rss exposes:
Site feed tab
- Enable site feed — toggle.
- Item count — 1-100 (default 20). Most recent N online posts.
- Excluded categories — categories whose posts should not appear in the site feed (e.g. "Internal updates"). Empty = include everything.
- Add to footer menu — when on, the plugin injects a
RSSentry into the resolved footer menu (no MenusPage edit needed).
Category feeds tab
- A list of
(category, item count, addToFooter)rows. - Add feed picker shows only categories that don't already have one.
- Remove deletes the row and the feed file on the next regeneration.
Force regenerate
Re-uploads every enabled feed from scratch + the XSL stylesheet. Useful after large config changes.
How items are built
Each <item> carries:
<title>—post.title<link>— absolute URL viapathToPublicUrl(baseUrl, lastPublishedPath)<guid isPermaLink="true">— same as<link><description>—post.excerptwhen set, otherwisemarkdownToPlainText(post.contentMarkdown, 300)(first 300 chars of plain text)<pubDate>— RFC-822-formattedpublishedAt(fallbackupdatedAtthencreatedAt)<author>— author's display name when available<enclosure>— whenpost.heroMediaIdis set, points at thelargevariant (fallback chain:large→defaultFormat→ first available)
Sort order: publishedAt DESC, with updatedAt / createdAt as fallbacks.
How it hooks in
The plugin subscribes to three lifecycle actions:
api.addAction("publish.complete", regenerate);
api.addAction("post.unpublished", regenerate);
api.addAction("post.deleted", regenerate);
Each handler:
- Regenerates the site feed — unless
post.primaryTermIdis inexcludedTermIds(in which case the post wouldn't appear anyway, and the existing file already excludes it). - Regenerates the category feed matching
post.primaryTermId, when one exists. - Persists path bookkeeping —
lastPublishedPathfor each feed, plus orphan-feed cleanup when a category is deleted.
It also registers a filter on menu.json.resolved to append RSS items to the footer (driven by per-feed addToFooter flags) and a Regeneration target so Themes → Regenerate site → RSS feeds runs the full pass.
When skipped
settings.baseUrlis empty — feed<link>elements need an absolute origin. Logs a warning and exits.- Site feed disabled AND no category feeds configured — nothing to do; short-circuits without uploading.
Stale path cleanup
When a category's slug changes, the next regeneration:
- Deletes the file at the old
lastPublishedPath. - Uploads the new file at the new path.
- Updates
lastPublishedPathinpluginConfigs.flexweg-rss.
Same flow when a feed is disabled (added to removedFeeds[] for one-shot cleanup).
Footer integration
Setting Add to footer on a feed appends a ResolvedMenuItem to the footer of /menu.json. Labels come from the plugin's i18n bundle:
- Site feed →
RSS - Category feed →
RSS — {{category name}}
Items append at the end of the existing footer. There's no reordering UI — admins wanting custom placement should leave the toggle off and add the feed URL by hand in Menus.
The settings page Save handler patches pluginConfigs.flexweg-rss and immediately re-runs publishMenuJson(...) so footer changes go live without waiting for the Firestore subscription to round-trip.
Toggle
Plugins → Plugins tab → flexweg-rss card → Enable / Disable.
Disabling does not delete feed files already on Flexweg. To clean up after a disable, use Force regenerate first to record current paths, then delete the files via Flexweg's file manager.
When changes apply
| Action | Files updated | Latency |
|---|---|---|
| Publish a post | Site feed (if not excluded) + matching category feed | Within seconds |
| Unpublish / delete | Same | Within seconds |
| Edit settings | Affected feeds + /menu.json | On Save |
| Slug change on a category | Old feed deleted, new feed uploaded | On the next publish in that category |
Internal details
- Source:
src/plugins/flexweg-rss/ - External in production builds: yes
- Hooks used:
publish.complete,post.unpublished,post.deletedactions;menu.json.resolvedfilter;registerRegenerationTarget - Storage paths:
/rss.xml,/<category-slug>/<category-slug>.xml,/rss.xml.xsl - Translations: 7 locales
Continue
- Sitemaps plugin
- Site features: RSS feeds — viewing feeds in readers
- Menus — manual placement