First of all, it's exactly how you would do it in a normal Django-powered site. The official docs for creating RSS or Atom feeds can be found here. That's one of the beauties of Wagtail, it keeps hold of many of the great features of Django.
But if you're not too familiar with Django, or the commonalities between vanilla Django and Wagtail, then hopefully this description of how I implemented an RSS feed on this site will help you.
There are two elements to an RSS feed in Django/Wagtail:
The Feed class gets all the relevant bits of data needed to serve the RSS feed to the client. It's essentially a class-based view.
The code for this can live anywhere within your codebase. I chose to create a new app for it. To do this I created a new folder in the root of my Wagtail project, called 'blog_feed' (it could be called whatever you want). Within this are two files:
I then added the app 'blog_feed' to the INSTALLED_APPS section of my base.py settings file.
With that done, back to the forms.py file. Below you can see the final code for my first RSS feed:
from django.db import models from django.contrib.syndication.views import Feed from blog.models import BlogPage class BlogsFeed(Feed): title = "My blog articles" link = "/blogs-feed/" description = "All of my blogs as they are published" def items(self): return BlogPage.objects.live().order_by('-date') def item_title(self, item): return item.title def item_description(self, item): return item.intro
In our first three lines we import the essential elements needed to create our Feed class. It will inherit the functionality of the basic Django Feed class, so we import that.
We also import the BlogPage model so that we can access the URLs, titles and descriptions that will make up the feed itself.
Then we create the class itself. As you can see in the first line, we subclass django.contrib.syndication.views.Feed by including it in the class definition.
The next three lines define the standard title, link and description values that begin all RSS feeds. You can see them in the output at chrxr.com/blog-feed. These are required!
<title>My blog articles</title> <link>https://chrxr.com/blogs-feed/</link> <description>All of my blogs as they are published</description>
Following that we define three standard methods for our Feed class. Again, all four of these are required to provide all the information necessary to build the feed.
The first method, items, gets the objects (pages) which we're going to list in the RSS feed from the database.
def items(self): return BlogPage.objects.live().order_by('-date')
The next two methods retrieve specific field information from each individual object. The first is populating the title for the link in the RSS feed. Usually this will be self.title, but it might be self.seo_title, or you may have another field on your blog model that you want to use.
The second method gets the description to go along with the link. This is more open to interpretation. I've used the self.intro field as it is often populated.
def item_title(self, item): return item.title def item_description(self, item): return item.intro
There's one final ingredient missing from this RSS pie, the actual links to the articles. Django's Feeds module has the power to extract these links itself, but only if the model listed in the RSS feed has a get_absolute_url() method.
This isn't a big problem though. I simply added the following line to my BlogPost model:
def get_absolute_url(self): return self.full_url
And that's it! The code for generating the feed is complete. Now onto the task of defining a URL to access the feed.
This bit is easy. You simply import your Feed class into the urls.py file, then add the line below to the urlpatterns section.
from blog_feed.feeds import BlogsFeed urlpatterns = [ #.... lots of URLs url(r'blog-feed/$', BlogsFeed()), # .... more URLs ]
So, when someone visits the URL http://chrxr.com/blog-feed, Wagtail initialises a new instance of the class BlogFeed, which responds to the browser with the feed of links defined in the class methods.
If you have an RSS browser extension installed (like me), this might display the links in the feed as a nice list. If not you'll likely just see a load of XML. Generally though, as long as you don't see an error, then it's working!