I was looking into improvements I could make to this blog, and for some reason I landed on adding an RSS feed. For two main reasons: it was something I've never done before, and it didn't seem that hard. Some preliminary research showed that I just needed a way to generate a structured XML document containing info and links to my blog posts.
So I did just that: made a simple PHP document that fetches blog post data from the database and spits out the correct XML (with some redactions for security):
<?php
$conn = mysqli_connect([REDACTED]);
if(!$conn) {
die('Could not connect: ' . mysqli_connect_error());
}
$sql = "SELECT id, title FROM posts ORDER BY id DESC LIMIT 10";
$result = mysqli_query($conn, $sql);
header("Content-type: text/xml");
echo "<?xml version='1.0' encoding='UTF-8'?>
<rss version='2.0'>
<channel>
<title>triplebatman</title>
<link>https://triplebatman.com/</link>
<description>RSS Feed for triplebatman's blog</description>
<language>en-us</language>";
while ($row = mysqli_fetch_assoc($result)) {
$title = $row["title"];
$id = $row["id"];
$link = "https://triplebatman.com/blog/post?id=$id";
$tag_sql = "SELECT name FROM tags WHERE id IN (SELECT DISTINCT(tag_id) FROM (SELECT * FROM posts LEFT JOIN posts_tags ON posts_tags.post_id = posts.id WHERE id = $id) as tags)";
$tag_result = mysqli_query($conn, $tag_sql);
$tags = [];
while($tag_row = mysqli_fetch_assoc($tag_result)) {
array_push($tags, $tag_row["name"]);
}
$tag_string = implode(", ", $tags);
$description = "post tags: $tag_string";
echo "<item>
<title>$title</title>
<link>$link</link>
<description>$description</description>
</item>";
}
echo "</channel></rss>";
?>
I decided to limit it to the last 10 posts, and I didn't want to go back and backfill description information so I just pulled the tags for each post and used them as the description. Once I had it generating XML that looked pretty good locally, I used the W3C Validator Tool, pasted in my XML, and was greeted with this:
So my feed was valid, but it wanted me to add guid elements to each of my feed items, and an "atom" link. Atom is just another web standard similar to RSS, and it seemed simple to add the necessary information. I just had to modify the root element in my XML document to include the standard, and then add a "self" link inside the channel section:
...
<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>
<channel>
<atom:link href='https://triplebatman.com/rss.php' rel='self' type='application/rss+xml' />
...
For the guid, the documentation says this can just be a permalink to the content, so I just added another reference to the blog link but tagged as guid:
...
<guid>$link</guid>
...
Then I revalidated, and...
Ok. I tried to debug this for quite a while, and I wasn't able to figure out how to get it resolved. The "self reference" is just a link to the rss.php URL for my blog, and the value is correct. Navigating to the help page says "Check the document referenced by the href attribute. If it is not the intended feed, correct it. This may not be a problem. At the current time, the feedvalidator does not probe to assess equivalence of documents." So I decided I didn't care about this recommendation, and decided to just test the feed.
I downloaded Thunderbird, as it is free and can subscribe to RSS feeds. I navigated the menus - "New account", "Feeds", and called it "triplebatman RSS". Then went to "Manage feed subscriptions", pasted in my RSS feed URL, and clicked "Add". The result?
So yeah, working RSS feed! Maybe this will be useful to someone - I assume at least some people still use RSS readers. One last thing I did was add a link tag to the shared head component for the blog to allow for auto-discovery of the RSS feed:
<link rel="alternate" type="application/rss+xml" title="triplebatman RSS feed" href="/rss.php" />
Then I used a Chrome extension to check if the RSS feed link was detected, and that seems to be working as well:
And that's that - fully discoverable and working RSS feed for my blog! It wasn't too difficult, and maybe one or two people will actually subscribe. Either was, this was a pretty fun little project. Cheers!