61

Adding an RSS Feed to Your Blog With Laravel

 5 years ago
source link: https://www.tuicool.com/articles/hit/J7JN7nM
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Hello again!

In another article, I decribed how I rebuilt my site with Laravel in a day . Though the website took shape within a day's work, I still had many essential features to include, such as RSS feeds, blog post comments, and structured data, to name a few. I wanted to explain my solution for implementing an RSS feed. This may be a simple solution but the point is that it works like a charm. So let's get started building an RSS feed for your site.

TLDR;

Here's the gist of my solution.

  1. Create a view file in the resources   folder. This file will have the XML structure which can be populated dynamically.

  2. Create an Artisan command called generate:feed   in the routes/console.php file.

  3. This command fetches all the posts and sends them to the RSS view. Then writes the returned XML formatted data to a file named rss.xml in the public folder.

I am sure you understood none of the above instructions, so let me explain this in a bit more detail.

The RSS View

Create a file in your resources/views   folder, I called it rss.blade.php . Paste in the code shown below. I'll explain as we go.

{!! '<'.'?'.'xml version="1.0" encoding="UTF-8" ?>' !!}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>{{ $site['name'] }}</title>
    <link>{{ $site['url'] }}</link>
    <description><![CDATA[{{ $site['description'] }}]]></description>
    <atom:link href="{{ $site['url'] }}" rel="self" type="application/rss+xml" />
    <language>{{ $site['language'] }}</language>
    <lastBuildDate>{{ $site['lastBuildDate'] }}</lastBuildDate>

    @foreach($posts as $post)
    <item>
      <title><![CDATA[{!! $post->title !!}]]></title>
      <link>{{ route('pages.post', $post->slug) }}</link>
      <guid isPermaLink="true">{{ route('pages.post', $post->slug) }}</guid>
      <description><![CDATA[{!! $post->description !!}]]></description>
      <content:encoded><![CDATA[{!! $post->content !!}]]></content:encoded>
      <dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">{{ $post->author }}</dc:creator>
      <pubDate>{{ $post->created_at->format(DateTime::RSS) }}</pubDate>
    </item>
    @endforeach
  </channel>
</rss>

As you might notice, we pass two variables to this view, $site   and  $posts . The first one contains some information about the your site. The second one contains an array of posts you want to include in this feed.

Next, we will create the Artisan command.

The Artisan Command

You may ask why we need to write all the logic in a command instead of a controller. I have a few reasons why I chose this method.

  1. I may want to call this command from the terminal.

  2. I may also call it from a controller.

  3. Since this command generates a file in the public folder there's no need for requests to go through Laravel.

Below is my code in the routes/console.php  file.

<?php
use Illuminate\Support\Facades\Storage;
use App\Models\Post;
Artisan::command('generate:feed', function () {
  $this->info("Generating RSS Feed");
  // It is important that you sort by the latest post
  $posts = Post::where('published', true)->latest()->get();

  $site = [
    'name' => 'YOUR SITE NAME', // Simplest Web
    'url' => 'YOUR SITE URL', // Link to your rss.xml. eg. https://simplestweb.in/rss.xml
    'description' => 'YOUR SITE DESCRIPTION',
    'language' => 'YOUR SITE LANGUAGE', // eg. en, en-IN, jp
    'lastBuildDate' => $posts[0]->created_at->format(DateTime::RSS), // This generates the latest posts date in RSS compatible format
  ];
  // Passes posts and site data into the rss.blade.view, out comes text in rss format
  $rssFileContents = view('rss', compact('posts', 'site'));
  // Saves the generated rss feed into a file called rss.xml in the public folder, this works only
  Storage::disk('local')->put('rss.xml', $rssFileContents);
  $this->info("Completed");
});

This is pretty basic stuff, so you should be able to recognize what the code does. First, we create an Artisan command. Then we fetch all the posts sorted by the most recent ones. Next, we create an array with our site details. Then we pass all this data to our rss.blade.php view file, which returns the formatted XML we need. Lastly, we write this to the rss.xml file in our public folder. That was't too hard, was it?

Updating the Layout File

Add the below code to the head   section of all your pages.

<!-- Change the title and href to your site -->
<link rel="alternate" type="application/rss+xml" title="Simplest Web" href="https://simplestweb.in/rss.xml" />

The above code lets the RSS readers know that there's an RSS feed in this site and points it to the URL.

That's About It

I hope you understood my solution to implementing a RSS Feed for a Laravel site. There's a lot more information you can add to this feed, and you can find more resources below. If you like this tutorial, do let me know. I will write more of them. If you get stuck anywhere in the tutorial, let me know, I'm happy to help. Thanks!

Additional Resources

  1. https://validator.w3.org

  2. / https://www.w3schools.com/xml/xml_rss.asp


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK