Blog

Blog

Growing our RSS Feed

This website is built using a static site generator. SSGs are a great fit for us because:

  • our website is like a brochure, with no dynamic elements
  • we value the efficiency of building the HTML in one shot, rather than a content management system rendering each page view in real-time
  • the “attack surface” of our website is minimised, because there is no content management system to secure
  • we can use traditional software development tools such as revision control systems

When we built this site, at the same time we launched with our new branding, we decided to adopt Grow. It parses our markdown content and renders it into HTML via Jinja2 templates. Grow is written in Python, a popular and flexible programming language which we’ve got years of experience using.

To make an RSS feed of our news and blog pages we created an additional page of content:

content/pages/news-rss.md
$title@: Faelix Blog and News Feed
$titles:
  nav: News Feed
$view: /views/rss.xml
$hidden: true
$path: /news.xml

description: "News articles and blog posts by the team at FAELIX."

channel:
    link: /news/
    language: en-gb
    rating: '(PICS-1.1 "http://vancouver-webpages.com/VWP1.0/" l gen true by "webmaster@faelix.net" on "2021.01.23T10:150000" for "https://faelix.net/" r (Com 1 SF -1 Can 0 Edu -1 V 0 P 0 Env -1 S 0 Gam -1 MC -1 Tol -1 ))'
    docs: http://tutorialspoint.com/rss
    ttl: 86400
    managingEditor: 'webmaster@faelix.net (FAELIX RSS Editor)'
    webMaster: 'webmaster@faelix.net (FAELIX RSS Webmaster)'
    image:
        url: /static/images/favicon/rss-icon-144x144.png
        width: 144
        height: 144
    posts: 8

That page is rendered through the following view to generate an RSS 2.0 XML file:

views/rss.xml

<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <atom:link href="{{ doc.url }}" rel="self" type="application/rss+xml" />

        <title>{{ doc.channel.title or doc.title }}</title>
        <link>{{ doc.channel.link }}</link>
        <description>{{ doc.channel.description or doc.description }}</description>

        <language>{{ doc.channel.language }}</language>
        <rating>{{ doc.channel.rating }}</rating>
        <copyright>Faelix Consultancy Services 2003-2006, Faelix Limited 2006-{{ None|datetime('Y') }}</copyright>

        <pubDate>{{ (g.docs('news', order_by='collection_path')|reverse|first).dates.published.strftime('%a, %d %b %Y %H:%M:%S') }} +0000</pubDate>
        <lastBuildDate>{{ None|datetime('EE, dd MMM Y HH:MM:SS') }} +0000</lastBuildDate>
        <generator>https://faelix.net/news/202101/adding-rss-to-grow/</generator>

        <docs>{{ doc.channel.docs }}</docs>
        <ttl>{{ doc.channel.ttl or 86400 }}</ttl>

        <managingEditor>{{ doc.channel.managingEditor }}</managingEditor>
        <webMaster>{{ doc.channel.webMaster }}</webMaster>

        {% if doc.channel.image %}
        <image>
            <title>{{ doc.channel.image.title or doc.channel.title or doc.title }}</title>
            <url>{{ doc.channel.image.url }}</url>
            <link>{% if env.host == podspec.meta.livedomain %}{{ env.scheme }}://{{ env.host }}{% endif %}{{ doc.channel.image.link or doc.channel.link }}</link>

            <width>{{ doc.channel.image.width }}</width>
            <height>{{ doc.channel.image.height }}</height>
            <description>{{ doc.channel.image.description or doc.channel.description or doc.description }}</description>
        </image>
        {% endif %}

        {% for post in (g.docs('news', order_by='collection_path')|reverse|list)[:doc.channel.posts] %}
            <item>
                <title>{{ post.title }}</title>
                <link>{{ post.url }}</link>
                <description>{{ post.description }}</description>

                <author>{{ podspec.meta.rss.author }} ({{ post.author }})</author>
                {% for tag in post.tags %}<category>{{ tag }}</category>
                {% endfor %}

                <guid>{{ post.url }}</guid>
                <pubDate>{{ post.dates.published.strftime('%a, %d %b %Y %H:%M:%S') }} +0000</pubDate>

                <source url="{{ post.url }}">{{ post.title }} — {{ podspec.title }}</source>
            </item>
        {% endfor %}
    </channel>
</rss>

And that’s all there is to it!