Skip to content

Instantly share code, notes, and snippets.

@knanne
Last active January 3, 2023 20:39
Show Gist options
  • Save knanne/3bcb3daad9faa1ab072a731d96ff2ae7 to your computer and use it in GitHub Desktop.
Save knanne/3bcb3daad9faa1ab072a731d96ff2ae7 to your computer and use it in GitHub Desktop.
JS Function to transform RSS feed into Bootstrap 4 Card
/*
* code to transform list of RSS feeds into bootstrap cards
* view my tutorial at https://knanne.github.io/posts/how-to-create-a-custom-rss-reader
* 1 DEPENDENCY - YQL: https://developer.yahoo.com/yql/
* Adhere to Google News GUIDELINES as standard for parsing RSS feeds
* (e.g. link to source, site author etc.)
* https://support.google.com/news/publisher/answer/4203?hl=en
*/
// make YQL query as url string
function make_query(url) {
return 'https://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from feednormalizer where url="' + url + '"') + '&format=json';
};
// define date format
var date_options = { weekday: 'short', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit'};
// define card creation functions
function make_cardheader(title, link, description) {
return '\
<div class="card-header text-left">\
<h5 class="card-title"' + (description ? 'title="' + description + '"' : '' ) + '><a href="' + link + '" target="_blank">' + title + '</a></h5>\
</div>';
};
function make_cardblock(link, title, date, source) {
return '\
<a href="' + link + '" target="_blank">\
<div class="card-block text-center">\
<div class="card-text text-muted">\
<p><b>' + title + '</b><br>\
<small>' + date + '<br>\
' + ( source ? ' - ' + source : '' ) + '\
</small>\
</p>\
</div>\
</div>\
</a>';
};
function make_cardfooter(last_updated) {
return '\
<div class="card-footer text-muted">\
<small>Last Updated: ' + last_updated + '</small>\
</div>';
};
// main build function
function buildFeedCard(url, container, feednum) {
// call yahoo for json from rss feed, parse json
$.getJSON(make_query(url), function (data, status, errorThrown) {
if (status === 'success') {
// define card string
card_string = '';
// open the feed card
card_string = card_string + '<div id="feed_' + feednum + '" class="card d-inline-flex justify-content-center">';
// get rss channel content from feed
var content = (data.query.results.hasOwnProperty('rss') ? data.query.results.rss.channel : data.query.results.feed);
var title = (content.title.constructor === Object ? content.title.content : content.title );
var link = (content.link.constructor === Array ? content.link[0].href || content.link[0] : content.link.href || content.link);
var description = (content.description ? content.description : null);
// add header to card
card_string = card_string + make_cardheader(title, link, description);
// loop thru each content entry, get content
$.each(content.item || content.entry, function(i, entry) {
// get item content dynamically
// because RSS feeds have different structures
if (content.description == "Google News") {
var title = entry.title.split(" - ")[0];
var source = entry.title.split(" - ")[1];
}
else {
var title = (entry.title.constructor === Object ? entry.title.content : entry.title );
var source = (entry.hasOwnProperty('creator') ? entry.creator : (entry.hasOwnProperty('author') ? entry.author.name : null));
}
var link = (entry.link.constructor === Array ? entry.link[0].href || entry.link[0] : entry.link.href || entry.link);
var date = new Date(Date.parse((entry.hasOwnProperty('pubDate') ? entry.pubDate : entry.updated)));
date = date.toLocaleDateString('en-US', date_options);
//append content to card
card_string = card_string + make_cardblock(link, title, date, source);
// dynamic trailing spacer
if ( i < 2 ) { card_string = card_string + '<hr>'; } else { card_string = card_string + '<br>'; }
// limit feed to 3 entries
return i < 2;
});
// last updated as query created time
var last_updated = new Date(Date.parse(data.query.created));
last_updated = last_updated.toLocaleDateString('en-US', date_options);
// append footer to card
card_string = card_string + make_cardfooter(last_updated);
// close the feed card
card_string = card_string + '</div>';
// append feed card to DOM
$(container).append(card_string);
} else if (status === 'error' || status === 'parsererror') {
console.log(errorThrown);
}
});
}
@knanne
Copy link
Author

knanne commented Mar 2, 2017

A tutorial for using this gist can be found at https://knanne.github.io/posts/how-to-create-a-custom-rss-reader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment