30 October 2018

Creating an Atom feed reader with Javascript

Creating an Atom feed reader with Javascript image

Atom is an extension of XML, just like RSS. Atom uses the .atom and .xml extensions and the application/atom+xml mimetype. Below is an example of an Atom feed from https://americanhorrorstory.style/. Having an atom feed on your website is a good idea, you can get more exposure via rss readers like Feedly, NewsBlur or NewsFeeder (a website/app i created).

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <generator uri="https://jekyllrb.com/" version="3.7.4">Jekyll</generator>
    <link href="https://americanhorrorstory.style/feed.xml" rel="self" type="application/atom+xml" />
    <link href="https://americanhorrorstory.style/" rel="alternate" type="text/html" hreflang="en" />
    <updated>2018-10-21T21:23:56+02:00</updated>
    <id>https://americanhorrorstory.style/</id>
    <title type="html">American Horror Story Outfits</title>
    <subtitle>This site is an inspiration style guide to some of the iconic American Horror Story characters. Read about the characters and their unique clothing style.</subtitle>
    <author>
        <name>Eva van der Weide</name>
    </author>
    <entry>
        <title type="html">APOCALYPSE - Madison</title>
        <link href="https://americanhorrorstory.style/2018/10/18/apocalypse-madison.html" rel="alternate" type="text/html" title="APOCALYPSE - Madison" />
        <published>2018-10-18T22:09:00+02:00</published>
        <updated>2018-10-18T22:09:00+02:00</updated>
        <id>https://americanhorrorstory.style/2018/10/18/apocalypse-madison</id>
        <content type="html" xml:base="https://americanhorrorstory.style/2018/10/18/apocalypse-madison.html">
          The witches are back! Who would’ve thought the witches from season 3 would make a comeback in season 8 of American Horror Story (named: Apocalypse).</content>
        <author>
            <name>Eva van der Weide</name>
        </author>
        <summary type="html">The witches are back!</summary>
        <media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://americanhorrorstory.style/images/meta-icons/android-chrome-512x512.png" />
    </entry>
</feed>

Let’s fetch the feed with Fetch API. You can use any valid Atom feed you want.

fetch('https://americanhorrorstory.style/feed')
  .then(response => response.text())
  .then(xml => { })

We will use the well supported DOMParser to parse the feed into a document. It’s important to set the type to “text/xml”, because it will default to “text/html”.

const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xml,"text/xml");

Let’s log the “xmlDoc” to the console. This will show a list of entry elements, which we need to display our posts.

Atom Feed console.log

Because the xmlDoc is of type “Document” and not “HTMLDocument”, we can’t use functions like “.querySelector” so we will use “.getElementsByTagName” to select the entry tags. This will return an array like object. To convert an array like object or iterable object, to an array, use Array.from(arrayLikeObject).

const html = Array.from(xmlDoc.getElementsByTagName('entry')).map(entry => `<div class="entry"></div>`);

This will return an array of strings containing HTML markup for our feed. Now we need to fill up the entry elements with content from the Atom feed. We can make this a bit easier by writing some helper functions.

// Get's a single child element by tag name
const t = (entry, tname) => entry.getElementsByTagName(tname)[0];

// Get date from an entry element
const date = entry => new Date(t(entry, 'published').textContent).getDate();

// Strip html tags to remove html tags like b, i, h1, etc.
const html2txt = html => html.replace(/<(?:.|\n)*?>/gm, '');

// Get excerpt from an entry content
const content = entry => html2txt(t(entry, 'content').textContent).slice(0, 200);

Now, replace the template string

`<div class="entry"></div>`

with the template string below.

`<div class="entry">
  <div class="timestamp">${date(entry)}</div>
  <a href="${t(entry, 'link').getAttribute('href')}">
  <h2 class="entry-title">${t(entry, 'title').innerHTML}</h2>
  </a>
  <div class="content">${content(entry)}&hellip;</div>
</div>`

Let’s join the html strings together and put it on the page.

<div id="items">loading........</div>
document.getElementById('items').innerHTML = html.join('');

You can checkout the full example, with code below. I’ve also added some extra css and html markup.

See the Pen Atom Feed Reader by sempostma (@Afirus) on CodePen.

The RSS reader I talked about earlier is a serverless javascript website/app called NewsFeeder. I’t parses Atom and RSS feeds, it’s free, it’s safe and has no sign-up.

NewsFeeder

Easily search for news on multiple platforms, find feeds on popular websites and more. Also works as a classic RSS/Atom reader.

Launch

NewsFeeder on Google Play.

rss icon follow us in feedly