Laravel Framework | PHP & MySQL | Tutorials

David Carr

Laravel create an RSS reed

In this post, I'll explain how to create an RSS feed.

First create a route that will respond with a feed, in this example I'm using a controller called BlogController and a method called feed.

Route::get('feed', 'BlogController@feed');

In your feed method query a model, in this case ordering by a created_at column and take the first 20 records, pass the data to a view:

public function feed()
{
    $posts = Post::orderBy('created_at', 'desc')->take(20)->get();
    return view('feed')->with(compact('posts'));
}

At the top of the view use a Request header to set the content type to application/xml

Start an rss and channel tags, set the title, description and link url

{{ Request::header('Content-Type : application/xml') }}

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>

<title>{{ config('app.name') }}</title>
<description>RSS Feed</description>
<link>{{ url('/') }}</link>

Next loop through the data

@foreach ($posts as $post)

Now create a blade php block, inside the @php using str_replace swap & and &amp; and chate quotes.
Remove any slashes from the title, description, and slug.

Optionally an image can be embedded, in this case, a check is made to see if an image column is not empty, if so create an image tag.

@php
$post->title = str_replace("&", "&amp;", $post->title);
$post->description = str_replace("&rdquo;", "”", $post->description);
$post->description = str_replace("&ldquo;", "“", $post->description);

$post->title = stripslashes($post->title);
$post->description = stripslashes($post->description);
$post->slug = stripslashes($post->slug);

if ($post->image !='') {
    $img = "<img src='".url($post->image)."' alt='".$post->title."' width='600'>";
} else {
    $img = null;
}
@endphp

Next, create an item tag and display the following tags:

title - the title of the post
description - using CDATA display the img variable and description
pubDate - the date the post was created using date & strtotime to format the date lastly set the timezone.
link and guid - the url to the post
atomLlink - the link to the post 

NOTE I make use of a column called $slug this is a custom field that holds a search engine friendly version of the title.

<item>
    <title>{{ $post->title }}</title>
    <description><![CDATA[{!! $img !!} {!! $post->description !!}]]></description>
    <pubDate>{{ date('D, d M Y H:i:s', strtotime($post->created_at)) }} GMT</pubDate>
    <link>{{ url($post->slug) }}</link>
    <guid>{{ url($post->slug) }}</guid>
    <atom:link href="{{ url($post->slug) }}" rel="self" type="application/rss+xml"/>
</item>

Lastly, close the foreach and tags.

@endforeach

</channel>
</rss>

Putting it all together

{{ Request::header('Content-Type : application/xml') }}

<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>

<title>{{ config('app.name') }}</title>
<description>RSS Feed</description>
<link>{{ url('/') }}</link>

@foreach ($posts as $post)

    @php
    $post->title = str_replace("&", "&amp;", $post->title);
    $post->description = str_replace("&rdquo;", "”", $post->description);
    $post->description = str_replace("&ldquo;", "“", $post->description);

    $post->title = stripslashes($post->title);
    $post->description = stripslashes($post->description);
    $post->slug = stripslashes($post->slug);

    if ($post->image !='') {
        $img = "<img src='".url($post->image)."' alt='".$post->title."' width='600'>";
    } else {
        $img = null;
    }
    @endphp

    <item>
        <title>{{ $post->title }}</title>
        <description><![CDATA[{!! $img !!} {!! $post->description !!}]]></description>
        <pubDate>{{ date('D, d M Y H:i:s', strtotime($post->created_at)) }} GMT</pubDate>
        <link>{{ url($post->slug) }}</link>
        <guid>{{ url($post->slug) }}</guid>
        <atom:link href="{{ url($post->slug) }}" rel="self" type="application/rss+xml"/>
    </item>

@endforeach

</channel>
</rss>

An optional step is to add a link tag to your html head section.

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

 

Domains are often purchased from multiple providers, keeping track of where a domain is and its DNS settings can be tricky. Domain Mapper solves this by listing all your domains in one place. View your DNS settings and receive reminders to renew your domains. Try it today.

Support my work by donating with PayPal.

Subscribe to my newsletter

Subscribe and get my books and product announcements.

© 2009 - 2021 DC Blog. All code MIT license. All rights reserved.