Last active
September 30, 2017 08:51
-
-
Save rayantony/15f599722afed58a1935e1a5e2559d9f to your computer and use it in GitHub Desktop.
rss via jquery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html> <head> | |
| <title>jquery.rss example</title> | |
| <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.4/moment.min.js"></script> | |
| <script src="http://d39dlwgeopmdw0.cloudfront.net/assets/web/rss/js/jquery.ray.rss.js" crossorigin="anonymous"></script> | |
| <script>window.jQuery(function($) {$("#rss-feeds").rss}) || document.write('<script src="jquery-rss.js"><\/script>')</script> | |
| <script> | |
| jQuery(function($) { | |
| $("#rss-feeds").rss("https://github.com/rayantony.atom", { | |
| limit: 15, | |
| effect: 'slideFastSynced'; | |
| }) | |
| }); | |
| </script> | |
| <style type="text/css"> | |
| body { font-family: Arial, Verdana, Trebuchet MS, Helvetica, lucida grande, "sans-serif"; font-size: 12px; } body > div { margin: 0px auto; width: 800px; } a { color: #37D; text-decoration: none; } a:hover { text-decoration: underline; } ul { list-style-type: none; margin: 0px; padding: 0px; } li { padding: 10px; border-top: 1px dashed #AAA; background-color: #EFEFEF; } li:first-child { border-top: none; } li:nth-child(2n) { background-color: white; } | |
| </style> | |
| </head> | |
| <body> | |
| <div> | |
| <h1>test</h1> | |
| <div id="rss-feeds"></div> | |
| </div> | |
| </body></html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function ($) { 'use strict'; var RSS = function (target, url, options, callback) { this.target = target; this.url = url; this.html = []; this.effectQueue = []; this.options = $.extend({ ssl: false, host: 'www.feedrapp.info', limit: null, key: null, layoutTemplate: '<ul>{entries}</ul>', entryTemplate: '<li><a href="{url}">[{author}@{date}] {title}</a><br/>{shortBodyPlain}</li>', tokens: {}, outputMode: 'json', dateFormat: 'dddd MMM Do', dateLocale: 'en', effect: 'show', offsetStart: false, offsetEnd: false, error: function () { console.log('jQuery RSS: url doesn\'t link to RSS-Feed'); }, onData: function () {}, success: function () {} }, options || {}); this.callback = callback || this.options.success; }; RSS.htmlTags = [ 'doctype', 'html', 'head', 'title', 'base', 'link', 'meta', 'style', 'script', 'noscript', 'body', 'article', 'nav', 'aside', 'section', 'header', 'footer', 'h1-h6', 'hgroup', 'address', 'p', 'hr', 'pre', 'blockquote', 'ol', 'ul', 'li', 'dl', 'dt', 'dd', 'figure', 'figcaption', 'div', 'table', 'caption', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'col', 'colgroup', 'form', 'fieldset', 'legend', 'label', 'input', 'button', 'select', 'datalist', 'optgroup', 'option', 'textarea', 'keygen', 'output', 'progress', 'meter', 'details', 'summary', 'command', 'menu', 'del', 'ins', 'img', 'iframe', 'embed', 'object', 'param', 'video', 'audio', 'source', 'canvas', 'track', 'map', 'area', 'a', 'em', 'strong', 'i', 'b', 'u', 's', 'small', 'abbr', 'q', 'cite', 'dfn', 'sub', 'sup', 'time', 'code', 'kbd', 'samp', 'var', 'mark', 'bdi', 'bdo', 'ruby', 'rt', 'rp', 'span', 'br', 'wbr' ]; RSS.prototype.load = function (callback) { var apiProtocol = 'http' + (this.options.ssl ? 's' : ''); var apiHost = apiProtocol + '://' + this.options.host; var apiUrl = apiHost + '?callback=?&q=' + encodeURIComponent(this.url); // set limit to offsetEnd if offset has been set if (this.options.offsetStart && this.options.offsetEnd) { this.options.limit = this.options.offsetEnd; } if (this.options.limit !== null) { apiUrl += '&num=' + this.options.limit; } if (this.options.key !== null) { apiUrl += '&key=' + this.options.key; } $.getJSON(apiUrl, callback); }; RSS.prototype.render = function () { var self = this; this.load(function (data) { try { self.feed = data.responseData.feed; self.entries = data.responseData.feed.entries; } catch (e) { self.entries = []; self.feed = null; return self.options.error.call(self); } var html = self.generateHTMLForEntries(); self.target.append(html.layout); if (html.entries.length !== 0) { if ($.isFunction(self.options.onData)) { self.options.onData.call(self); } var container = $(html.layout).is('entries') ? html.layout : $('entries', html.layout); self.appendEntriesAndApplyEffects(container, html.entries); } if (self.effectQueue.length > 0) { self.executeEffectQueue(self.callback); } else if ($.isFunction(self.callback)) { self.callback.call(self); } }); }; RSS.prototype.appendEntriesAndApplyEffects = function (target, entries) { var self = this; $.each(entries, function (idx, entry) { var $html = self.wrapContent(entry); if (self.options.effect === 'show') { target.before($html); } else { $html.css({ display: 'none' }); target.before($html); self.applyEffect($html, self.options.effect); } }); target.remove(); }; RSS.prototype.generateHTMLForEntries = function () { var self = this; var result = { entries: [], layout: null }; $(this.entries).each(function () { var entry = this; var offsetStart = self.options.offsetStart; var offsetEnd = self.options.offsetEnd; var evaluatedString; // offset required if (offsetStart && offsetEnd) { if (index >= offsetStart && index <= offsetEnd) { if (self.isRelevant(entry, result.entries)) { evaluatedString = self.evaluateStringForEntry( self.options.entryTemplate, entry ); result.entries.push(evaluatedString); } } } else { // no offset if (self.isRelevant(entry, result.entries)) { evaluatedString = self.evaluateStringForEntry( self.options.entryTemplate, entry ); result.entries.push(evaluatedString); } } }); if (!!this.options.entryTemplate) { // we have an entryTemplate result.layout = this.wrapContent( this.options.layoutTemplate.replace('{entries}', '<entries></entries>') ); } else { // no entryTemplate available result.layout = this.wrapContent('<div><entries></entries></div>'); } return result; }; RSS.prototype.wrapContent = function (content) { if (($.trim(content).indexOf('<') !== 0)) { // the content has no html => create a surrounding div return $('<div>' + content + '</div>'); } else { // the content has html => don't touch it return $(content); } }; RSS.prototype.applyEffect = function ($element, effect, callback) { var self = this; switch (effect) { case 'slide': $element.slideDown('slow', callback); break; case 'slideFast': $element.slideDown(callback); break; case 'slideSynced': self.effectQueue.push({ element: $element, effect: 'slide' }); break; case 'slideFastSynced': self.effectQueue.push({ element: $element, effect: 'slideFast' }); break; } }; RSS.prototype.executeEffectQueue = function (callback) { var self = this; this.effectQueue.reverse(); var executeEffectQueueItem = function () { var item = self.effectQueue.pop(); if (item) { self.applyEffect(item.element, item.effect, executeEffectQueueItem); } else if (callback) { callback(); } }; executeEffectQueueItem(); }; RSS.prototype.evaluateStringForEntry = function (string, entry) { var result = string; var self = this; $(string.match(/(\{.*?\})/g)).each(function () { var token = this.toString(); result = result.replace(token, self.getValueForToken(token, entry)); }); return result; }; RSS.prototype.isRelevant = function (entry, entries) { var tokenMap = this.getTokenMap(entry); if (this.options.filter) { if (this.options.filterLimit && (this.options.filterLimit === entries.length)) { return false; } else { return this.options.filter(entry, tokenMap); } } else { return true; } }; RSS.prototype.getFormattedDate = function (dateString) { // If a custom formatting function is provided, use that. if (this.options.dateFormatFunction) { return this.options.dateFormatFunction(dateString); } else if (typeof moment !== 'undefined') { // If moment.js is available and dateFormatFunction is not overriding it, // use it to format the date. var date = moment(new Date(dateString)); if (date.locale) { date = date.locale(this.options.dateLocale); } else { date = date.lang(this.options.dateLocale); } return date.format(this.options.dateFormat); } else { // If all else fails, just use the date as-is. return dateString; } }; RSS.prototype.getTokenMap = function (entry) { if (!this.feedTokens) { var feed = JSON.parse(JSON.stringify(this.feed)); delete feed.entries; this.feedTokens = feed; } return $.extend({ feed: this.feedTokens, url: entry.link, author: entry.author, date: this.getFormattedDate(entry.publishedDate), title: entry.title, body: entry.content, shortBody: entry.contentSnippet, bodyPlain: (function (entry) { var result = entry.content .replace(/<script[\\r\\\s\S]*<\/script>/mgi, '') .replace(/<\/?[^>]+>/gi, ''); for (var i = 0; i < RSS.htmlTags.length; i++) { result = result.replace(new RegExp('<' + RSS.htmlTags[i], 'gi'), ''); } return result; })(entry), shortBodyPlain: entry.contentSnippet.replace(/<\/?[^>]+>/gi, ''), index: $.inArray(entry, this.entries), totalEntries: this.entries.length, teaserImage: (function (entry) { try { return entry.content.match(/(<img.*?>)/gi)[0]; } catch (e) { return ''; } })(entry), teaserImageUrl: (function (entry) { try { return entry.content.match(/(<img.*?>)/gi)[0].match(/src="(.*?)"/)[1]; } catch (e) { return ''; } })(entry) }, this.options.tokens); }; RSS.prototype.getValueForToken = function (_token, entry) { var tokenMap = this.getTokenMap(entry); var token = _token.replace(/[\{\}]/g, ''); var result = tokenMap[token]; if (typeof result !== 'undefined') { return ((typeof result === 'function') ? result(entry, tokenMap) : result); } else { throw new Error('Unknown token: ' + _token + ', url:' + this.url); } }; $.fn.rss = function (url, options, callback) { new RSS(this, url, options, callback).render(); return this; // Implement chaining };})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment