Skip to content

RSS Feeds ​

Siteman CMS includes built-in RSS/Atom feed generation powered by Spatie's Laravel Feed package. RSS feeds allow users to subscribe to your content using feed readers and enable content syndication.

Understanding RSS Feeds in Siteman ​

RSS feeds in Siteman:

  • Are created as special page types
  • Generate XML feeds automatically from published content
  • Support both RSS and Atom formats
  • Include page metadata (title, author, published date, content)
  • Update automatically when content changes

Creating an RSS Feed ​

Step 1: Create a Feed Page ​

  1. Navigate to Content > Pages in the admin panel
  2. Click New Page
  3. Configure the feed:
    • Title: "RSS Feed" or "Blog Feed"
    • Slug: "/feed" or "/blog/feed"
    • Type: Select "RSS Feed"
    • Feed Title: Your feed's title (e.g., "My Blog - Latest Posts")
    • Feed Description: Brief description of your feed content
    • Feed Language: Select language (e.g., "en-US")
    • Published At: Select current date/time
  4. Click Create

The RSS feed is now accessible at the slug you specified (e.g., https://yoursite.com/feed).

Step 2: Verify the Feed ​

Visit your feed URL in a browser. You should see XML content:

xml
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>My Blog - Latest Posts</title>
    <link href="https://yoursite.com/feed" rel="self"/>
    <updated>2024-01-15T10:30:00Z</updated>
    <id>https://yoursite.com/feed</id>
    <!-- Feed items -->
</feed>

Feed Configuration ​

Feed Metadata ​

Configure feed metadata when creating/editing the RSS Feed page:

Feed Title: The name of your feed

Example: "TechBlog - Latest Articles"
Default: Uses site name from GeneralSettings

Feed Description: Brief description of your feed's content

Example: "Stay updated with the latest web development tutorials and tips"
Default: Uses site description from GeneralSettings

Feed Language: Language code for the feed

Example: "en-US", "de-DE", "es-ES"
Default: "en-US"

What Gets Included ​

By default, the RSS feed includes all published pages with:

  • Title
  • URL (computed_slug)
  • Summary/excerpt
  • Author name
  • Published date
  • Last updated date

Customizing Feed Content ​

Filtering Feed Items ​

To create a feed for specific content (e.g., only blog posts), you need to modify the feed items source.

Example: Blog-specific feed

  1. Create a custom page type that extends RssFeed:
php
<?php

namespace App\PageTypes;

use Siteman\Cms\PageTypes\RssFeed as BaseRssFeed;
use Siteman\Cms\Models\Page as PageModel;
use Illuminate\Http\Request;
use Spatie\Feed\Feed;
use Spatie\Feed\Helpers\ResolveFeedItems;

class BlogRssFeed extends BaseRssFeed
{
    public function render(Request $request, PageModel $page)
    {
        // Get only posts from a specific blog
        $blogId = $page->getMeta('blog_id');
        $items = PageModel::where('parent_id', $blogId)
            ->published()
            ->get()
            ->map(fn($item) => $item->toFeedItem());

        $settings = app(\Siteman\Cms\Settings\GeneralSettings::class);

        return new Feed(
            $page->getMeta('feed_title', $settings->site_name),
            $items,
            $request->url(),
            'feed::atom',
            $page->getMeta('feed_description', $settings->description),
            $page->getMeta('feed_language', 'en-US'),
            '',
            'atom',
            '',
        );
    }
}
  1. Register the custom page type in your AppServiceProvider:
php
public function boot(): void
{
    app('siteman.page-types')->register(
        'blog-feed',
        \App\PageTypes\BlogRssFeed::class
    );
}

Customizing Feed Items ​

The Page model includes a toFeedItem() method that converts pages to feed items:

php
// src/Models/Page.php (excerpt)
public function toFeedItem(): FeedItem
{
    return FeedItem::create()
        ->id($this->slug)
        ->title($this->title)
        ->summary($this->excerpt ?? '')
        ->updated($this->updated_at)
        ->link($this->computed_slug)
        ->authorName($this->author->name ?? '');
}

To customize feed items, you can:

Option 1: Add excerpt field to pages

php
// In a migration
Schema::table('pages', function (Blueprint $table) {
    $table->text('excerpt')->nullable();
});

// When creating/updating pages
$page->update([
    'excerpt' => 'A brief summary of the page content...',
]);

Option 2: Use meta description

php
$page->update([
    'meta' => [
        'description' => 'Description that will appear in the feed',
    ],
]);

// Modify toFeedItem() to use meta
public function toFeedItem(): FeedItem
{
    return FeedItem::create()
        ->id($this->slug)
        ->title($this->title)
        ->summary($this->getMeta('description', ''))
        ->updated($this->updated_at)
        ->link($this->computed_slug)
        ->authorName($this->author->name ?? '');
}

Multiple RSS Feeds ​

Create multiple feeds for different content sections:

Main Blog Feed ​

  • URL: /blog/feed
  • Content: All blog posts
  • Use case: General blog subscribers

Tag-Specific Feeds ​

  • URL: /blog/laravel/feed
  • Content: Posts tagged with "Laravel"
  • Use case: Topic-specific subscribers

Author Feeds ​

  • URL: /author/john/feed
  • Content: Posts by specific author
  • Use case: Following specific authors

Adding Feed Discovery ​

Help users and feed readers discover your feeds by adding feed discovery meta tags to your theme layout:

blade
{{-- In your theme layout head section --}}
<link rel="alternate"
      type="application/atom+xml"
      title="My Blog - Atom Feed"
      href="{{ url('/feed') }}">

<link rel="alternate"
      type="application/rss+xml"
      title="My Blog - RSS Feed"
      href="{{ url('/feed') }}">

Add subscription links to your site:

blade
{{-- Simple feed link --}}
<a href="/feed" class="feed-link">
    Subscribe via RSS
</a>

{{-- With icon --}}
<a href="/feed" class="feed-link">
    <svg><!-- RSS icon --></svg>
    Subscribe
</a>

{{-- Multiple format options --}}
<div class="feed-options">
    <a href="/feed">Atom Feed</a>
    <a href="/feed.rss">RSS Feed</a>
</div>

Testing Your Feed ​

Feed Validators ​

Test your feed with these validators:

Feed Readers ​

Test with popular feed readers:

Browser Testing ​

Most modern browsers will display formatted XML when you visit the feed URL directly.

Feed Performance ​

Caching ​

Consider caching RSS feeds for better performance:

php
// In your custom RssFeed page type
use Illuminate\Support\Facades\Cache;

public function render(Request $request, PageModel $page)
{
    return Cache::remember(
        "feed:{$page->id}",
        now()->addHour(),
        function () use ($request, $page) {
            // Generate feed
            return parent::render($request, $page);
        }
    );
}

Clear the cache when content updates:

php
// In your Page model
protected static function booted(): void
{
    static::saved(function ($page) {
        // Clear feed cache when a page is saved
        Cache::forget('feed:main');
    });
}

Pagination ​

Limit feed items to improve performance:

php
// In custom RssFeed page type
$items = PageModel::published()
    ->orderBy('published_at', 'desc')
    ->take(50) // Limit to 50 most recent items
    ->get()
    ->map(fn($item) => $item->toFeedItem());

Feed Security ​

Rate Limiting ​

Protect your feed from excessive requests:

php
// In RouteServiceProvider or web.php
Route::middleware(['throttle:60,1'])->group(function () {
    // Siteman routes including feed
});

Content Filtering ​

Be cautious about what content you include:

  • Exclude draft or unpublished content
  • Sanitize HTML in feed items
  • Consider partial content vs. full content

Advanced Feed Features ​

Extend toFeedItem() to include images:

php
public function toFeedItem(): FeedItem
{
    $feedItem = FeedItem::create()
        ->id($this->slug)
        ->title($this->title)
        ->summary($this->excerpt ?? '')
        ->updated($this->updated_at)
        ->link($this->computed_slug)
        ->authorName($this->author->name ?? '');

    // Add featured image if exists
    if ($this->hasMedia('featured_image')) {
        $feedItem->image($this->getFirstMediaUrl('featured_image'));
    }

    return $feedItem;
}

Adding Categories ​

Include tags as feed categories:

php
// Extend FeedItem to support categories
$feedItem->category($this->tags->pluck('name')->toArray());

Full Content vs Excerpts ​

Choose between full content or excerpts:

php
// Excerpt only (better for driving traffic)
->summary($this->excerpt)

// Full content (better for readers)
->summary($this->content)

// Hybrid approach
->summary($this->excerpt)
->content($this->content) // If FeedItem supports it

Troubleshooting ​

Feed Returns 404 ​

  1. Verify the page exists and is published
  2. Check the slug is correct
  3. Verify route registration: php artisan route:list | grep feed
  4. Clear route cache: php artisan route:clear

Feed Shows Empty ​

  1. Ensure pages are published (published_at in the past)
  2. Check getFeedItems() method returns items
  3. Verify pages have required fields (title, slug, published_at)

Feed Validation Errors ​

  1. Check XML is well-formed
  2. Ensure dates are in ISO 8601 format
  3. Verify URLs are absolute, not relative
  4. Check for special characters that need escaping

Feed Not Updating ​

  1. Clear cache: php artisan cache:clear
  2. Check if caching is aggressive
  3. Verify updated_at is being set on page updates

SEO and RSS Feeds ​

Benefits of RSS feeds for SEO:

  • Content Distribution: Wider content reach
  • Backlinks: Feed aggregators may link back
  • Freshness: Signals regular content updates
  • Indexing: Helps search engines discover new content

Best practices:

  • Include full or substantial excerpts
  • Use descriptive feed titles and descriptions
  • Keep feed URLs permanent (don't change)
  • Submit feeds to feed directories
  • Blog - Create blog content for your feed
  • Tags - Organize feed content by tags
  • Page Types - Understanding RSS Feed page type
  • Settings - Configure site-wide feed defaults

Released under the MIT License.