Skip to content

jekylldown 0.3.4: add_feed() and use_r_bloggers() - #1

Merged
allanvc merged 3 commits into
mainfrom
feat/feeds
Sep 2, 2026
Merged

jekylldown 0.3.4: add_feed() and use_r_bloggers()#1
allanvc merged 3 commits into
mainfrom
feat/feeds

Conversation

@allanvc

@allanvc allanvc commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Two new exported functions, add_feed() and use_r_bloggers(), plus a hook in new_site(). Version bumped to 0.3.4.

The bug. al-folio uses title: blank in _config.yml to mean "build the site title from first_name/middle_name/last_name". The theme's layouts understand that; the jekyll-feed plugin does not, so every stock al-folio site publishes an Atom feed titled, literally, blank (and blank | R for category feeds). Changing title is not an option: al-folio also uses title != 'blank' to add journal = {<title>} to the BibTeX it generates for posts.

The feature. R users on jekylldown will want R-Bloggers, which requires a full-text feed with R posts only. jekyll-feed can generate per-category feeds, but they inherit the same title bug.

How it works

add_feed() writes _includes/atom-feed.xml, a copy of jekyll-feed's own template with one change (the title assignment becomes a site.title == 'blank' check that falls back to the plugin's original line), plus one-line feed pages that render it: feed.xml and, per category, feed/<category>.xml. jekyll-feed skips generating any feed whose file already exists, so the pages replace the plugin's output without disabling it ({% feed_meta %} still works). The template needs only core Liquid filters, so the pages also work on sites without the plugin.

Where the template comes from, in order, so it follows jekyll-feed's development instead of freezing a copy inside the package:

  1. The gem installed for the site — the version pinned in Gemfile.lock, which is what the local build and the deploy workflow render with. Looked up under jekylldown's isolated GEM_HOME first (locked version, else the newest), then via bundle show jekyll-feed for gems installed elsewhere.
  2. That version's tag on GitHub (raw.githubusercontent.com/jekyll/jekyll-feed/v<version>/...) when the gem is not installed yet — never the default branch, which may be ahead of what the site runs. Network failures fall through silently.
  3. The copy shipped in inst/jekyll-feed/feed-0.17.0.xml, with a message saying to re-run after bundle_install().

Safety rails:

  • The patch is a textual replacement of one anchor line ({% assign title = site.title | default: site.name %}). If the template does not contain exactly that line, add_feed() aborts with a message pointing at the issue tracker instead of writing a broken feed.
  • The include carries a provenance marker on line 2 (jekylldown: rendered from jekyll-feed 0.17.0 (gem)), placed after the XML declaration (anything before <?xml ?> makes the document ill-formed — that bit me while doing this by hand). Re-running add_feed() after a gem upgrade regenerates it; force = TRUE regenerates unconditionally.
  • An atom-feed.xml, feed.xml or feed/<cat>.xml without the marker / not rendering the include is the user's own and is never touched.

use_r_bloggers(category = "R") does the site side of an R-Bloggers submission in one call: add_feed("R"), the link back to R-Bloggers that they require (a marker-delimited block under the header bar of _pages/blog.md on al-folio, replaced on re-runs; the snippet is printed on other themes), and the public feed URL to submit, built from url + baseurl.

new_site(theme = "al-folio") — and migrate_hugo() through it — now calls add_feed() (silently, like the footer credit) so fresh sites never ship a feed titled "blank".

Tests

tests/testthat/test-feed.R (no Ruby, no network — a fake gem is planted under a redirected R_USER_DATA_DIR):

  • the patch applies to the template and leaves the rest intact; the marker sits right after the XML declaration;
  • a template without the anchor is refused;
  • add_feed() writes the include from the installed gem and both pages with the expected front matter;
  • idempotence, regeneration on gem upgrade, the locked version winning over a newer gem lying around, force;
  • hand-written include and pages are left alone (category page still written);
  • offline fallback to the bundled copy;
  • lockfile parsing reads the spec line, not jekyll-feed (~> 0.9) dependency lines;
  • drift detector: the jekyll-feed gem actually installed on the machine still has the anchor line (skips when no gem);
  • use_r_bloggers() on al-folio (feed, link placement after the header-bar endif, URL, idempotence), on other themes (snippet, no link), and argument validation.

Full suite green; R CMD check --no-manual: 0 errors, 0 warnings, 2 pre-existing environment NOTEs (archive not installed for checking; "unable to verify current time").

Verified on a real site

Ran use_r_bloggers() on a copy of allanvc.github.io (al-folio, title: blank, jekyll-feed 0.17.0 installed → source gem), then build_site():

  • feed.xml title: Allan Quadros; feed/R.xml title: Allan Quadros | R (was blank / blank | R);
  • both XML files well-formed; feed/R.xml has the 7 posts with categories: R, full <content>, nothing else;
  • the R-Bloggers link renders under the blog header.

The same fix was applied by hand to that site in allanvc/allanvc.github.io@5c0a0d7; this PR is the generalisation.

Notes for review

  • Roxygen 8.1 rewrites RoxygenNote as Config/roxygen2/version and touches three unrelated .Rd files; that regeneration is its own commit so the feature diff stays readable.
  • Category names are matched verbatim ("R""r"), same as jekyll-feed's own where: "categories" filter; the path keeps the case too (/feed/R.xml), consistent with what the plugin would generate.
  • The link block on the blog page uses al-folio's Font Awesome classes and its /blog/category/<slug>/ archive URL; other themes only get the plain snippet, on purpose — I did not want to guess where each theme lists posts.
  • Worth opening upstream: an issue on alshedivat/al-folio, since the "blank" feed title affects every stock al-folio site, not only jekylldown ones.

Render the site's Atom feeds from a site-level copy of jekyll-feed's
template, patched so al-folio's `title: blank` convention yields the
author's full name as the feed title (the plugin alone prints the
literal word "blank"), plus optional per-category full-text feeds --
the kind of feed R-Bloggers requires.

- R/feed.R: add_feed(category, dir, force) and use_r_bloggers(category,
  dir). The template is taken from the jekyll-feed gem installed for the
  site (Gemfile.lock version; isolated GEM_HOME first, then `bundle
  show`), then that version's tag on GitHub, then the copy shipped in
  inst/jekyll-feed/. The patch replaces one anchor line and aborts with
  a clear message if upstream moves it; the include records its
  provenance so a gem upgrade regenerates it, and hand-written files
  are never touched.
- new_site(theme = "al-folio") (and migrate_hugo() through it) call
  add_feed() so fresh sites never publish a feed titled "blank".
- tests/testthat/test-feed.R: patch, sources, idempotence, upgrades,
  user files, lockfile parsing, a drift detector against the installed
  gem, and use_r_bloggers on al-folio and other themes.
- NEWS, README, getting-started vignette.
RoxygenNote gives way to Config/roxygen2/version, the package Rd gains
the Authors block, and two cross-package links now point at the topic
alias (knitr::render_jekyll, servr::httw).
On Windows runners the session tempdir comes back in 8.3 short form
(RUNNER~1) while site_root() returns the long form, so the equality on
the include path failed there. Normalise both sides, as the page paths
already are.
@allanvc
allanvc merged commit f94e32b into main Sep 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant