Join 26,000+ Laravel Developers and join the free Laravel Newsletter
Learn to Create an RSS Feed from Scratch in Laravel
Laravel Tutorials / updated: April 03, 2018

Learn to Create an RSS Feed from Scratch in Laravel

Creating an RSS feed in Laravel isn’t the most challenging task, but using a package and a few tips can help you create an RSS feed relatively quick.

We are going to use the spatie/laravel-feed package to walk through going from a brand new Laravel 5.6 project to serving RSS feeds.

Setup

The first thing we need to do is create a new Laravel project. You can use the laravel new installer command, or use composer:

composer create-project --prefer-dist laravel/laravel:5.6 rss-example
cd rss-example

Next, let’s install the spatie/laravel-feed package and copy the configuration file into the project:

composer require spatie/laravel-feed
php artisan vendor:publish \
  --provider="Spatie\Feed\FeedServiceProvider" \
  --tag="config"

Modeling the Data

We are going to create some test model data to set up our RSS feed for a collection of Events. Think of this model as an RSS feed for upcoming events for a church or a meetup group. The model name Event is superfluous, but that’s the best name I could come up with, so we’ll go with it!

First up, let’s create the model for our RSS feed along with a migration
file and a factory file:

php artisan make:model Event -mf
Model created successfully.
Factory created successfully.
Created Migration: 2018_04_03_033916_create_events_table

In the migration class, let’s define the generic, simple schema:

public function up()
{
    Schema::create('events', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->text('description');
        $table->string('author');
        $table->timestamps();
    });
}

Next up, open the database/factories/EventFactory.php file and add the following:

$factory->define(App\Event::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'description' => "<p>".implode("</p>\n\n<p>", $faker->paragraphs(rand(3,6)))."</p>",
        'author' => $faker->name,
    ];
});

There might be a better way to generate an HTML description, but I am assuming that the UI for creating an event would provide a WYSIWYG field for writing the description.

We can use our schema and factory to seed some test data in order to finish setting up our RSS feed:

php artisan make:seeder EventsSeeder

In the created EventsSeeder class, generate some seed events we can use:

<?php

use Illuminate\Database\Seeder;

class EventsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory('App\Event', 50)->create();
    }
}

Next, add the EventsSeeder to the DatabaseSeeder class:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $this->call(EventsSeeder::class);
    }
}

Depending on how you created the files, you might need to run composer dump-autoload to pick up the seeder files. You can then run migrations (assuming you’ve set up a database following the documentation) to create the tables and populate the database with some seed data:

php artisan migrate:fresh --seed
Dropped all tables successfully.
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table
Migrating: 2018_04_03_034457_create_events_table
Migrated:  2018_04_03_034457_create_events_table
Seeding: EventsSeeder

And just like that, we have some fake events to work with!

Setting up the Model

Using Spatie’s package, we implement an interface to support the spatie/laravel-feed package configuration with our App\Event model.

We will have two methods for using our Event model with a feed:

  1. The toFeedItem() method to support Spatie’s Feedable interface
  2. A getFeedItems() static method to get all the feed items

First up, here’s the implementation for the toFeedItem() method with our schema in the app/Event.php file:

<?php

namespace App;

use Spatie\Feed\Feedable;
use Spatie\Feed\FeedItem;
use Illuminate\Database\Eloquent\Model;

class Event extends Model implements Feedable
{
    public function toFeedItem()
    {
        return FeedItem::create()
            ->id($this->id)
            ->title($this->title)
            ->summary($this->description)
            ->updated($this->updated_at)
            ->link($this->link)
            ->author($this->author);
    }
}

At the moment, this method won’t work quite right, because we don’t have a link attribute but other than that, this method is pretty straightforward.

We are converting an individual model instance to a FeedItem instance to generate the final RSS format.

Next, we’ll add the getFeedItems() static method to the Event.php file:

public static function getFeedItems()
{
   return static::all();
}

We are merely returning all results as a collection that is converted to individual FeedItem instances.

The last method we’ll add to the model is an accessor for the $event->link attribute:

public function getLinkAttribute()
{
    return route('events.show', $this);
}

Using implicit route model binding, we are generating the link property on the model that will be used to link to individual RSS items.

Routes and the Events Controller

The last piece we need to work on is creating a controller and a route so the route('events.show', $this) will work as expected.

First, let’s generate a controller:

php artisan make:controller EventsController
Controller created successfully.

Inside the EventsController create a show() method that returns the model which results in a JSON response. We are not going to flesh out the EventsController@show method and return HTML in this tutorial; I’ll leave that up to you:

<?php

namespace App\Http\Controllers;

use App\Event;
use Illuminate\Http\Request;

class EventsController extends Controller
{
    public function show(Request $request, Event $event)
    {
        return $event;
    }
}

Next, we need to configure the main RSS feed route in the published config/feed.php file we generated earlier:

<?php

return [
    'feeds' => [
        'main' => [
            'items' => 'App\Event@getFeedItems',

            /*
             * The feed will be available on this url.
             */
            'url' => '/events.rss',

            'title' => 'Upcoming Events',
        ],
    ],
];

Last up, we need to add the RSS route and the EventsController@show route to the bottom of routes/web.php:

Route::get('/events/{event}', 'EventsController@show')
    ->name('events.show');

Route::feeds();

The Route::feeds() method is a route macro that defines the necessary route(s) from our config/feed.php configuration. We use the {event} route parameter and take advantage of implicit route model binding that we used earlier to generate the event link from within the model.

Our feed should be available at /events.rss now!

Linking to the Feed

You can also add an RSS link to the default welcome page by adding @include('feed::links') in the <head> of the view:

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>
        @include('feed::links')
{{-- ... --}}

If you visit the homepage of the project, you’ll get something like the following link tag:

<link
  rel="alternate"
  type="application/rss+xml"
  href="http://127.0.0.1:8000/events.rss"
  title="Upcoming Events"
>

With hardly any effort, we created a working RSS feed for our model data, and you can imagine how little you’d have to do to add RSS to existing model data in your applications!

Learn More

Check out the laravel-feed GitHub page for the source code and package setup.

I wrote about Route macros yesterday in Laravel Route Tips to Improve Routing, and the Laravel feed package has an excellent route macro defined in the FeedServiceProvider that you should check out.

Laravel News Partners

Newsletter

Join the weekly newsletter and never miss out on new tips, tutorials, and more.