Black Friday sale is now on! 50% off Laravel: The Modular Way. Learn more

Laravel create an RSS reed

David Carr

Laravel Framework PHP & MySQL Tutorials

  • Putting it all together
  • 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'/>

     

    Laravel Modules Book by David Carr

    Help support the blog so that I can continue creating new content!

    Subscribe to my newsletter

    Subscribe and get my books and product announcements.

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