Skip to content

Add site-wide RSS and Atom feeds#74

Open
samdark wants to merge 1 commit into
masterfrom
add-site-wide-feeds
Open

Add site-wide RSS and Atom feeds#74
samdark wants to merge 1 commit into
masterfrom
add-site-wide-feeds

Conversation

@samdark

@samdark samdark commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

  • generate root /feed.xml and /rss.xml from all feed-enabled collections
  • resolve site-feed entry URLs through each entry collection and list root feed files in dry-run output
  • document site-wide feeds and update the roadmap feed item

Tests

  • make test -- --filter FeedGeneratorTest
  • make test -- --filter testBuildGeneratesFeedsForCollectionsWithFeedEnabled
  • make test -- --filter testDryRunListsFilesWithoutWriting
  • make psalm
  • make test

Summary by CodeRabbit

  • New Features

    • Site-wide Atom (/feed.xml) and RSS 2.0 (/rss.xml) feeds now aggregate entries from all feed-enabled collections, respecting the feed_limit setting.
  • Documentation

    • Updated build command, configuration, and collection documentation to explain site-wide and per-collection feed generation behavior and limits.
    • Updated roadmap to reflect collection and site-wide feed generation.

Copilot AI review requested due to automatic review settings June 13, 2026 09:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds site-wide Atom and RSS feed generation (/feed.xml and /rss.xml) that aggregates entries from collections with feed enabled, alongside per-collection feeds. FeedGenerator gains new public methods and internal collection-aware URL resolution. BuildCommand orchestrates aggregation and output. Tests verify behavior and documentation describes the feature.

Changes

Site-wide Feed Generation

Layer / File(s) Summary
FeedGenerator site-wide feed API
src/Build/FeedGenerator.php
New public methods generateSiteAtom(), generateSiteRss(), writeSiteAtomFile(), and writeSiteRssFile() create site-wide feeds. Atom and RSS document writers accept optional per-entry collection maps for URL resolution. Helper methods collectionPath(), feedPath(), and siteFeedCollection() handle URL construction and synthetic root collection creation.
BuildCommand site-wide feed integration
src/Console/BuildCommand.php
After per-collection feeds complete, aggregates all feed-enabled entries, sorts by descending date (null dates last), and generates/writes /feed.xml and /rss.xml. Dry-run mode tracks $hasFeeds flag and conditionally lists root feed files when any collection has feed enabled.
Unit tests for site-wide feeds
tests/Unit/Build/FeedGeneratorTest.php, tests/Unit/Console/BuildCommandTest.php
New test testSiteFeedsUseSiteMetadataAndEntryCollections() validates site-wide Atom and RSS generation with multiple collections and per-entry collection URLs. BuildCommandTest assertions verify site-root feed artifacts and dry-run file enumeration.
Documentation updates
docs/commands.md, docs/configuration.md, docs/content.md, roadmap.md
Updated to describe site-wide feed generation at /feed.xml and /rss.xml aggregating feed-enabled collections, feed_limit defaults, and integration with build and collection configuration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit hops through feeds both far and wide,
Now sites can feast on aggregated pride,
Where collections dance in RSS embrace,
And Atom flows through every feed-filled space,
The build command spins feeds with glee!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add site-wide RSS and Atom feeds' directly and concisely describes the main feature added in this pull request, which is the generation of site-wide feed files at the root level.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-site-wide-feeds

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/Unit/Build/FeedGeneratorTest.php (1)

277-330: ⚡ Quick win

Add a focused unit test for writeSiteAtomFile() / writeSiteRssFile() paths.

This new test validates in-memory site feed generation well, but the new site-level file-writing methods would be safer with a direct unit test (mirroring testFeedFilesCanBeWrittenDirectly()), so regressions are isolated without relying only on command-level integration.

🧪 Suggested test addition
+    public function testSiteFeedFilesCanBeWrittenDirectly(): void
+    {
+        $generator = new FeedGenerator(new ContentProcessorPipeline(new MarkdownProcessor(new MarkdownRenderer())));
+        $collections = ['blog' => $this->collection];
+        $entries = $this->createEntries();
+        $atomPath = sys_get_temp_dir() . '/yiipress-site-feed-atom-' . uniqid() . '.xml';
+        $rssPath = sys_get_temp_dir() . '/yiipress-site-feed-rss-' . uniqid() . '.xml';
+
+        try {
+            $generator->writeSiteAtomFile($atomPath, $this->siteConfig, $collections, $entries);
+            $generator->writeSiteRssFile($rssPath, $this->siteConfig, $collections, $entries);
+            assertFileExists($atomPath);
+            assertFileExists($rssPath);
+        } finally {
+            if (is_file($atomPath)) {
+                unlink($atomPath);
+            }
+            if (is_file($rssPath)) {
+                unlink($rssPath);
+            }
+        }
+    }

As per coding guidelines, **/*Test.php: For each piece of code add a test using phpunit.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/Unit/Build/FeedGeneratorTest.php` around lines 277 - 330, Add a focused
unit test that exercises FeedGenerator::writeSiteAtomFile() and
FeedGenerator::writeSiteRssFile() directly (similar to the existing
testFeedFilesCanBeWrittenDirectly pattern) rather than only generating feeds
in-memory: reuse the setup from testSiteFeedsUseSiteMetadataAndEntryCollections
(create the same collections and entries and instantiate FeedGenerator with
ContentProcessorPipeline/MarkdownProcessor), create two temporary file paths,
call writeSiteAtomFile($siteConfig, $collections, $entries, $atomPath) and
writeSiteRssFile($siteConfig, $collections, $entries, $rssPath), assert the
files were created, and assert their contents contain the same key strings
checked in testSiteFeedsUseSiteMetadataAndEntryCollections (site title, site
links, entry links, and the self atom/rss link) to ensure the file-writing paths
are covered.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Build/FeedGenerator.php`:
- Around line 120-129: The call to $this->createFileWriter() in
YiiPress\Build\FeedGenerator::writeSiteAtomFile is reported as undefined; ensure
the private function createFileWriter(string $path): XMLWriter is present with
the exact name and signature in the same final class
YiiPress\Build\FeedGenerator (or change its visibility to match usage if
needed), then rebuild/refresh packaging and autoload so CI picks up the updated
class (run composer dump-autoload, clear any PHAR/classmap caches and OPcache,
and verify no duplicate/stale FeedGenerator class exists in vendor or packaged
artifacts); if you intentionally moved or renamed createFileWriter, update
writeSiteAtomFile to call the new method name instead.

---

Nitpick comments:
In `@tests/Unit/Build/FeedGeneratorTest.php`:
- Around line 277-330: Add a focused unit test that exercises
FeedGenerator::writeSiteAtomFile() and FeedGenerator::writeSiteRssFile()
directly (similar to the existing testFeedFilesCanBeWrittenDirectly pattern)
rather than only generating feeds in-memory: reuse the setup from
testSiteFeedsUseSiteMetadataAndEntryCollections (create the same collections and
entries and instantiate FeedGenerator with
ContentProcessorPipeline/MarkdownProcessor), create two temporary file paths,
call writeSiteAtomFile($siteConfig, $collections, $entries, $atomPath) and
writeSiteRssFile($siteConfig, $collections, $entries, $rssPath), assert the
files were created, and assert their contents contain the same key strings
checked in testSiteFeedsUseSiteMetadataAndEntryCollections (site title, site
links, entry links, and the self atom/rss link) to ensure the file-writing paths
are covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 085be0e3-c3c5-45cb-80ec-00c61924b606

📥 Commits

Reviewing files that changed from the base of the PR and between 315ad8d and 5c1f86b.

📒 Files selected for processing (8)
  • docs/commands.md
  • docs/configuration.md
  • docs/content.md
  • roadmap.md
  • src/Build/FeedGenerator.php
  • src/Console/BuildCommand.php
  • tests/Unit/Build/FeedGeneratorTest.php
  • tests/Unit/Console/BuildCommandTest.php

Comment on lines +120 to +129
public function writeSiteAtomFile(
string $path,
SiteConfig $siteConfig,
array $collections,
array $entries,
): void {
$xml = $this->createFileWriter($path);
$collection = $this->siteFeedCollection($siteConfig);
$this->writeAtomDocument($xml, $siteConfig, $collection, $this->limitEntries($collection, $entries), $collections);
$xml->flush();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== FeedGenerator class definitions =="
rg -nP --type=php 'namespace\s+YiiPress\\Build;|class\s+FeedGenerator\b'

echo
echo "== FeedGenerator method declarations related to failing call =="
rg -nP --type=php -C2 'function\s+writeSiteAtomFile\s*\(|function\s+createFileWriter\s*\('

echo
echo "== Autoload/classmap references to FeedGenerator =="
rg -nP 'YiiPress\\\\Build\\\\FeedGenerator|FeedGenerator\.php'

Repository: yiipress/engine

Length of output: 3226


CI fatal: createFileWriter() undefined in writeSiteAtomFile()—check for stale/packaged FeedGenerator

  • src/Build/FeedGenerator.php defines a single final class YiiPress\Build\FeedGenerator.
  • That same class declares private function createFileWriter(string $path): XMLWriter (around line ~391) and writeSiteAtomFile() calls $this->createFileWriter($path) (around line ~122).
  • If CI still reports the method as undefined at the call site, the build is likely loading an older/stale FeedGenerator artifact (PHAR/vendor/autoload/classmap cache). Inspect the CI packaging/autoload inputs used during build.
🧰 Tools
🪛 GitHub Actions: Run Tests / 0_test.txt

[error] 122-122: Console command "build" failed: PHP Fatal error — Call to undefined method YiiPress\Build\FeedGenerator::createFileWriter().

🪛 GitHub Actions: Run Tests / test

[error] 122-122: Error: Call to undefined method YiiPress\Build\FeedGenerator::createFileWriter() while running console command "build". Triggered from writeSiteAtomFile() via /app/src/Console/BuildCommand.php(759).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Build/FeedGenerator.php` around lines 120 - 129, The call to
$this->createFileWriter() in YiiPress\Build\FeedGenerator::writeSiteAtomFile is
reported as undefined; ensure the private function createFileWriter(string
$path): XMLWriter is present with the exact name and signature in the same final
class YiiPress\Build\FeedGenerator (or change its visibility to match usage if
needed), then rebuild/refresh packaging and autoload so CI picks up the updated
class (run composer dump-autoload, clear any PHAR/classmap caches and OPcache,
and verify no duplicate/stale FeedGenerator class exists in vendor or packaged
artifacts); if you intentionally moved or renamed createFileWriter, update
writeSiteAtomFile to call the new method name instead.

Source: Pipeline failures

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.

2 participants