added GeoRSS support thanks to @fredzilla. Fixes #15.

This commit is contained in:
Dylan Greene
2013-09-14 16:29:34 -04:00
parent 05b63b7ece
commit a73e525251
4 changed files with 77 additions and 44 deletions

View File

@@ -24,8 +24,8 @@ function RSS (options, items) {
this.managingEditor = options.managingEditor; this.managingEditor = options.managingEditor;
this.webMaster = options.webMaster; this.webMaster = options.webMaster;
this.ttl = options.ttl; this.ttl = options.ttl;
//option to return feed as GeoRSS //option to return feed as GeoRSS is set automatically if feed.lat/long is used
this.georss = options.georss || false; this.geoRSS = options.geoRSS || false;
this.items = items || []; this.items = items || [];
this.item = function (options) { this.item = function (options) {
@@ -39,7 +39,7 @@ function RSS (options, items) {
author: options.author, author: options.author,
date: options.date, date: options.date,
lat: options.lat, lat: options.lat,
lng: options.lng, long: options.long,
enclosure: options.enclosure || false enclosure: options.enclosure || false
}; };
@@ -61,7 +61,6 @@ function ifTruePush(bool, array, data) {
} }
function generateXML (data){ function generateXML (data){
// todo: xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
var channel = []; var channel = [];
channel.push({ title: { _cdata: data.title } }); channel.push({ title: { _cdata: data.title } });
@@ -105,11 +104,10 @@ function generateXML (data){
ifTruePush(item.author || data.author, item_values, { 'dc:creator': { _cdata: item.author || data.author } }); ifTruePush(item.author || data.author, item_values, { 'dc:creator': { _cdata: item.author || data.author } });
ifTruePush(item.date, item_values, { pubDate: new Date(item.date).toGMTString() }); ifTruePush(item.date, item_values, { pubDate: new Date(item.date).toGMTString() });
//Add lat and long if GeoRSS is true. //Set GeoRSS to true if lat and long are set
if(data.georss){ data.geoRSS = data.geoRSS || (item.lat && item.long);
ifTruePush(item.lat, item_values, {'geo:lat': item.lat}); ifTruePush(item.lat, item_values, {'geo:lat': item.lat});
ifTruePush(item.lng, item_values, {'geo:long': item.lng}); ifTruePush(item.long, item_values, {'geo:long': item.long});
}
if( item.enclosure && item.enclosure.url ) { if( item.enclosure && item.enclosure.url ) {
if( item.enclosure.file ) { if( item.enclosure.file ) {
@@ -144,18 +142,20 @@ function generateXML (data){
'xmlns:dc': 'http://purl.org/dc/elements/1.1/', 'xmlns:dc': 'http://purl.org/dc/elements/1.1/',
'xmlns:content': 'http://purl.org/rss/1.0/modules/content/', 'xmlns:content': 'http://purl.org/rss/1.0/modules/content/',
'xmlns:atom': 'http://www.w3.org/2005/Atom', 'xmlns:atom': 'http://www.w3.org/2005/Atom',
'version': '2.0' version: '2.0'
}; };
//only add namespace if GeoRSS is true //only add namespace if GeoRSS is true
if(data.georss){ if(data.geoRSS){
_attr['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#'; _attr['xmlns:geo'] = 'http://www.w3.org/2003/01/geo/wgs84_pos#';
} }
return { rss: [ return {
{ '_attr': _attr }, rss: [
{ 'channel': channel } { _attr: _attr },
] }; { channel: channel }
]
};
} }
module.exports = RSS; module.exports = RSS;

View File

@@ -10,7 +10,8 @@
"Michael R. Lange", "Michael R. Lange",
"Victor Jonsson", "Victor Jonsson",
"Danny Graham", "Danny Graham",
"Patrick Garman <contact@pmgarman.me>" "Patrick Garman <contact@pmgarman.me>",
"Fred Morstatter"
], ],
"repository": "repository":
{ {
@@ -24,8 +25,8 @@
}, },
"dependencies": "dependencies":
{ {
"xml": ">= 0.0.4", "xml": "~0.0.4",
"mime": ">= 1.2.9" "mime": "~1.2.11"
}, },
"devDependencies": { "devDependencies": {
"chai": "~1.7.2", "chai": "~1.7.2",

View File

@@ -2,7 +2,7 @@
[![NPM](https://nodei.co/npm/rss.png?downloads=true)](https://nodei.co/npm/rss/) [![NPM](https://nodei.co/npm/rss.png?downloads=true)](https://nodei.co/npm/rss/)
> Fast and simple RSS generator/builder for Node projects. > Fast and simple RSS generator/builder for Node projects. Supports enclosures and GeoRSS.
## Install ## Install
@@ -34,7 +34,6 @@ var feed = new RSS(feedOptions);
* `language` _optional_ **string** The language of the content of this feed. * `language` _optional_ **string** The language of the content of this feed.
* `categories` _optional_ **array of strings** One or more categories this feed belongs to. * `categories` _optional_ **array of strings** One or more categories this feed belongs to.
* `pubDate` _optional_ **Date object or date string** The publication date for content in the feed * `pubDate` _optional_ **Date object or date string** The publication date for content in the feed
* `georss` _optional_ **boolean** Whether to make the feed a GeoRSS feed. Default is `false`.
* `ttl` _optional_ **integer** Number of minutes feed can be cached before refreshing from source. * `ttl` _optional_ **integer** Number of minutes feed can be cached before refreshing from source.
### Add items to a feed ### Add items to a feed
@@ -61,8 +60,8 @@ feed.item(itemOptions);
* `date` **Date object or date string** The date and time of when the item was created. Feed * `date` **Date object or date string** The date and time of when the item was created. Feed
readers use this to determine the sort order. Some readers will also use it to determine readers use this to determine the sort order. Some readers will also use it to determine
if the content should be presented as unread. if the content should be presented as unread.
* `lat` _required if is a GeoRSS feed_ **number** The latitude coordinate of the item. * `lat` _optional_ **number** The latitude coordinate of the item.
* `lng` _required if is a GeoRSS feed_ **number** The longitude coordinate of the item. * `long` _optional_ **number** The longitude coordinate of the item.
#### Feed XML #### Feed XML
@@ -82,22 +81,21 @@ var RSS = require('rss');
/* lets create an rss feed */ /* lets create an rss feed */
var feed = new RSS({ var feed = new RSS({
title: 'title', title: 'title',
description: 'description', description: 'description',
feed_url: 'http://example.com/rss.xml', feed_url: 'http://example.com/rss.xml',
site_url: 'http://example.com', site_url: 'http://example.com',
image_url: 'http://example.com/icon.png', image_url: 'http://example.com/icon.png',
docs: 'http://example.com/rss/docs.html', docs: 'http://example.com/rss/docs.html',
author: 'Dylan Greene', author: 'Dylan Greene',
managingEditor: 'Dylan Greene', managingEditor: 'Dylan Greene',
webMaster: 'Dylan Greene', webMaster: 'Dylan Greene',
copyright: '2013 Dylan Greene', copyright: '2013 Dylan Greene',
language: 'en', language: 'en',
categories: ['Category 1','Category 2','Category 3'], categories: ['Category 1','Category 2','Category 3'],
pubDate: 'May 20, 2012 04:00:00 GMT', pubDate: 'May 20, 2012 04:00:00 GMT',
georss: true, //set this flag if you wish for the feed to be returned in GeoRSS. A lat/lng field will be expected for each item. ttl: '60'
ttl: '60' });
});
/* loop over data and add to feed */ /* loop over data and add to feed */
feed.item({ feed.item({
@@ -108,9 +106,9 @@ feed.item({
categories: ['Category 1','Category 2','Category 3','Category 4'], // optional - array of item categories categories: ['Category 1','Category 2','Category 3','Category 4'], // optional - array of item categories
author: 'Guest Author', // optional - defaults to feed author property author: 'Guest Author', // optional - defaults to feed author property
date: 'May 27, 2012' // any format that js Date can parse. date: 'May 27, 2012' // any format that js Date can parse.
// lat: 33.417974, //latitude field. Provide if georss is true in the feed setup. lat: 33.417974, //optional latitude field for GeoRSS
// lng: -111.933231, //longitude field. Provide if georss is true in the feed setup. long: -111.933231, //optional longitude field for GeoRSS
enclosure : {url:'...', file:'path-to-file'} // optional enclosure : {url:'...', file:'path-to-file'} // optional enclosure
}); });
// cache the xml to send to clients // cache the xml to send to clients

View File

@@ -72,7 +72,6 @@ describe('rss module', function(done) {
var expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><image><url>http://example.com/icon.png</url><title>title</title><link>http://example.com</link></image><generator>Example Generator</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Dylan Greene]]></author><pubDate>Sun, 20 May 2012 04:00:00 GMT</pubDate><copyright><![CDATA[2013 Dylan Green]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Dylan Green]]></managingEditor><webMaster><![CDATA[Dylan Green]]></webMaster><docs>http://example.com/rss/docs.html</docs><ttl>60</ttl><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><link>http://example.com/article2</link><guid isPermaLink="true">http://example.com/article2</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Fri, 25 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 3]]></title><description><![CDATA[description 3]]></description><link>http://example.com/article3</link><guid isPermaLink="false">item3</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Sat, 26 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 4 & html test with <strong>]]></title><description><![CDATA[description 4 uses some <strong>html</strong>]]></description><link>http://example.com/article4?this&amp;that</link><guid isPermaLink="true">http://example.com/article4?this&amp;that</guid><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Sun, 27 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 5 & test for categories]]></title><description><![CDATA[description 5]]></description><link>http://example.com/article5</link><guid isPermaLink="true">http://example.com/article5</guid><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><category><![CDATA[Category 4]]></category><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Mon, 28 May 2012 04:00:00 GMT</pubDate></item></channel></rss>'; var expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><image><url>http://example.com/icon.png</url><title>title</title><link>http://example.com</link></image><generator>Example Generator</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Dylan Greene]]></author><pubDate>Sun, 20 May 2012 04:00:00 GMT</pubDate><copyright><![CDATA[2013 Dylan Green]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Dylan Green]]></managingEditor><webMaster><![CDATA[Dylan Green]]></webMaster><docs>http://example.com/rss/docs.html</docs><ttl>60</ttl><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><link>http://example.com/article2</link><guid isPermaLink="true">http://example.com/article2</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Fri, 25 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 3]]></title><description><![CDATA[description 3]]></description><link>http://example.com/article3</link><guid isPermaLink="false">item3</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Sat, 26 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 4 & html test with <strong>]]></title><description><![CDATA[description 4 uses some <strong>html</strong>]]></description><link>http://example.com/article4?this&amp;that</link><guid isPermaLink="true">http://example.com/article4?this&amp;that</guid><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Sun, 27 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 5 & test for categories]]></title><description><![CDATA[description 5]]></description><link>http://example.com/article5</link><guid isPermaLink="true">http://example.com/article5</guid><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><category><![CDATA[Category 4]]></category><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Mon, 28 May 2012 04:00:00 GMT</pubDate></item></channel></rss>';
var result = feed.xml(); var result = feed.xml();
expect(result).to.have.length(expectedResult.length);
expect(result).to.equal(expectedResult); expect(result).to.equal(expectedResult);
done(); done();
}); });
@@ -132,7 +131,6 @@ describe('rss module', function(done) {
var expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><generator>RSS for Node</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Dylan Greene]]></author><pubDate>Sun, 20 May 2012 04:00:00 GMT</pubDate><copyright><![CDATA[2013 Dylan Green]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Dylan Green]]></managingEditor><webMaster><![CDATA[Dylan Green]]></webMaster><docs>http://example.com/rss/docs.html</docs><ttl>60</ttl><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><link>http://example.com/article2</link><guid isPermaLink="true">http://example.com/article2</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Fri, 25 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 3]]></title><description><![CDATA[description 3]]></description><link>http://example.com/article3</link><guid isPermaLink="false">item3</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Sat, 26 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 4 & html test with <strong>]]></title><description><![CDATA[description 4 uses some <strong>html</strong>]]></description><link>http://example.com/article4?this&amp;that</link><guid isPermaLink="true">http://example.com/article4?this&amp;that</guid><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Sun, 27 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 5 & test for categories]]></title><description><![CDATA[description 5]]></description><link>http://example.com/article5</link><guid isPermaLink="true">http://example.com/article5</guid><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><category><![CDATA[Category 4]]></category><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Mon, 28 May 2012 04:00:00 GMT</pubDate></item></channel></rss>'; var expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><generator>RSS for Node</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Dylan Greene]]></author><pubDate>Sun, 20 May 2012 04:00:00 GMT</pubDate><copyright><![CDATA[2013 Dylan Green]]></copyright><language><![CDATA[en]]></language><managingEditor><![CDATA[Dylan Green]]></managingEditor><webMaster><![CDATA[Dylan Green]]></webMaster><docs>http://example.com/rss/docs.html</docs><ttl>60</ttl><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><link>http://example.com/article2</link><guid isPermaLink="true">http://example.com/article2</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Fri, 25 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 3]]></title><description><![CDATA[description 3]]></description><link>http://example.com/article3</link><guid isPermaLink="false">item3</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Sat, 26 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 4 & html test with <strong>]]></title><description><![CDATA[description 4 uses some <strong>html</strong>]]></description><link>http://example.com/article4?this&amp;that</link><guid isPermaLink="true">http://example.com/article4?this&amp;that</guid><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Sun, 27 May 2012 04:00:00 GMT</pubDate></item><item><title><![CDATA[item 5 & test for categories]]></title><description><![CDATA[description 5]]></description><link>http://example.com/article5</link><guid isPermaLink="true">http://example.com/article5</guid><category><![CDATA[Category 1]]></category><category><![CDATA[Category 2]]></category><category><![CDATA[Category 3]]></category><category><![CDATA[Category 4]]></category><dc:creator><![CDATA[Guest Author]]></dc:creator><pubDate>Mon, 28 May 2012 04:00:00 GMT</pubDate></item></channel></rss>';
var result = feed.xml(); var result = feed.xml();
expect(result).to.have.length(expectedResult.length);
expect(result).to.equal(expectedResult); expect(result).to.equal(expectedResult);
done(); done();
}); });
@@ -178,7 +176,43 @@ describe('rss module', function(done) {
'</channel></rss>'; '</channel></rss>';
var result = feed.xml(); var result = feed.xml();
expect(result).to.have.length(expectedResult.length); expect(result).to.equal(expectedResult);
done();
});
it('should work with geoRSS', function(done) {
var feed = new RSS({
title: 'title',
description: 'description',
feed_url: 'http://example.com/rss.xml',
site_url: 'http://example.com',
author: 'Dylan Greene'
});
feed.item({
title: 'item 1',
description: 'description 1',
url: 'http://example.com/article1',
date: 'May 24, 2012 04:00:00 GMT',
lat: 12232,
long: 13333.23323
});
feed.item({
title: 'item 2',
description: 'description 2',
url: 'http://example.com/article1',
date: 'May 24, 2012 04:00:00 GMT'
});
var expectedResult = '<?xml version="1.0" encoding="UTF-8"?>\n<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"><channel><title><![CDATA[title]]></title><description><![CDATA[description]]></description><link>http://example.com</link><generator>RSS for Node</generator><lastBuildDate>' + new Date().toUTCString() +'</lastBuildDate><atom:link href="http://example.com/rss.xml" rel="self" type="application/rss+xml"/>'+
'<author><![CDATA[Dylan Greene]]></author>' +
'<item><title><![CDATA[item 1]]></title><description><![CDATA[description 1]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate><geo:lat>12232</geo:lat><geo:long>13333.23323</geo:long></item>'+
'<item><title><![CDATA[item 2]]></title><description><![CDATA[description 2]]></description><link>http://example.com/article1</link><guid isPermaLink="true">http://example.com/article1</guid><dc:creator><![CDATA[Dylan Greene]]></dc:creator><pubDate>Thu, 24 May 2012 04:00:00 GMT</pubDate></item>'+
'</channel></rss>';
var result = feed.xml();
expect(result).to.equal(expectedResult); expect(result).to.equal(expectedResult);
done(); done();
}); });