diff --git a/website/api/controllers/articles/view-basic-article.js b/website/api/controllers/articles/view-basic-article.js
index bd2b67f6ba..6673616a44 100644
--- a/website/api/controllers/articles/view-basic-article.js
+++ b/website/api/controllers/articles/view-basic-article.js
@@ -45,6 +45,8 @@ module.exports = {
}
}
+ let articleCategorySlug = pageUrlSuffix.split('/')[0];
+
// Setting the pages meta title and description from the articles meta tags, as well as an article image, if provided.
// Note: Every article page should have a 'articleTitle' and a 'authorFullName' meta tag.
// Note: Leaving title and description as `undefined` in our view means we'll default to the generic title and description set in layout.ejs.
@@ -68,6 +70,7 @@ module.exports = {
pageTitleForMeta,
pageDescriptionForMeta,
pageImageForMeta: thisPage.meta.articleImageUrl || undefined,
+ articleCategorySlug
};
}
diff --git a/website/api/controllers/download-rss-feed.js b/website/api/controllers/download-rss-feed.js
new file mode 100644
index 0000000000..2dae5c7445
--- /dev/null
+++ b/website/api/controllers/download-rss-feed.js
@@ -0,0 +1,141 @@
+module.exports = {
+
+
+ friendlyName: 'Download rss feed',
+
+
+ description: 'Generate and return an RSS feed for a category of Fleet\'s articles',
+
+
+ inputs: {
+
+ categoryName: {
+ type: 'string',
+ required: true,
+ isIn: [
+ 'success-stories',
+ 'securing',
+ 'releases',
+ 'engineering',
+ 'guides',
+ 'announcements',
+ 'deploy',
+ 'podcasts',
+ 'report',
+ 'articles',
+ ],
+ }
+
+ },
+
+
+ exits: {
+ success: { outputFriendlyName: 'RSS feed XML', outputType: 'string' },
+ badConfig: { responseType: 'badConfig' },
+ },
+
+
+ fn: async function ({categoryName}) {
+
+ if (!_.isObject(sails.config.builtStaticContent)) {
+ throw {badConfig: 'builtStaticContent'};
+ } else if (!_.isArray(sails.config.builtStaticContent.markdownPages)) {
+ throw {badConfig: 'builtStaticContent.markdownPages'};
+ }
+
+ // Start building the rss feed
+ let rssFeedXml = '';
+
+ // Build the description and title for this RSS feed.
+ let articleCategoryTitle = '';
+ let categoryDescription = '';
+ switch(categoryName) {
+ case 'success-stories':
+ articleCategoryTitle = 'Success stories | Fleet blog';
+ categoryDescription = 'Read about how others are using Fleet and osquery.';
+ break;
+ case 'securing':
+ articleCategoryTitle = 'Security | Fleet blog';
+ categoryDescription = 'Learn more about how we secure Fleet.';
+ break;
+ case 'releases':
+ articleCategoryTitle = 'Releases | Fleet blog';
+ categoryDescription = 'Read about the latest release of Fleet.';
+ break;
+ case 'engineering':
+ articleCategoryTitle = 'Engineering | Fleet blog';
+ categoryDescription = 'Read about engineering at Fleet and beyond.';
+ break;
+ case 'guides':
+ articleCategoryTitle = 'Guides | Fleet blog';
+ categoryDescription = 'Learn more about how to use Fleet to accomplish your goals.';
+ break;
+ case 'announcements':
+ articleCategoryTitle = 'Announcements | Fleet blog';
+ categoryDescription = 'The latest news from Fleet.';
+ break;
+ case 'deploy':
+ articleCategoryTitle = 'Deployment guides | Fleet blog';
+ categoryDescription = 'Learn more about how to deploy Fleet.';
+ break;
+ case 'podcasts':
+ articleCategoryTitle = 'Podcasts | Fleet blog';
+ categoryDescription = 'Listen to the Future of Device Management podcast';
+ break;
+ case 'report':
+ articleCategoryTitle = 'Reports | Fleet blog';
+ categoryDescription = '';
+ break;
+ case 'articles':
+ articleCategoryTitle = 'Fleet blog | Fleet for osquery';
+ categoryDescription = 'Read all articles from Fleet\'s blog.';
+ }
+
+ let rssFeedTitle = `${_.escape(articleCategoryTitle)}`;
+ let rssFeedDescription = `${_.escape(categoryDescription)}`;
+ let rsslastBuildDate = `${_.escape(new Date(Date.now()))}`;
+ let rssFeedImage = `${_.escape('https://fleetdm.com'+categoryName)}${_.escape(articleCategoryTitle)}${_.escape('https://fleetdm.com/images/fleet-logo-square@2x.png')}`;
+
+ rssFeedXml += `${rssFeedTitle}${rssFeedDescription}${rsslastBuildDate}${rssFeedImage}`;
+
+
+ // Determine the subset of articles that will be used to squirt out an XML string.
+ let articlesToAddToFeed = [];
+ if (categoryName === 'articles') {
+ // If the category is `articles` we'll build a rss feed that contains all articles
+ articlesToAddToFeed = sails.config.builtStaticContent.markdownPages.filter((page)=>{
+ if(_.startsWith(page.htmlId, 'articles')) {
+ return page;
+ }
+ });//∞
+ } else {
+ // If the user requested a specific category, we'll only build a feed with articles in that category
+ articlesToAddToFeed = sails.config.builtStaticContent.markdownPages.filter((page)=>{
+ if(_.startsWith(page.url, '/'+categoryName)) {
+ return page;
+ }
+ });//∞
+ }
+
+ // Iterate through the filtered array of articles, adding - elements for each article.
+ for (let pageInfo of articlesToAddToFeed) {
+ let rssItemTitle = `${_.escape(pageInfo.meta.articleTitle)}`;
+ let rssItemDescription = `${_.escape(pageInfo.meta.description)}`;
+ let rssItemLink = `${_.escape('https://fleetdm.com'+pageInfo.url)}`;
+ let rssItemPublishDate = `${_.escape(new Date(pageInfo.meta.publishedOn).toJSON())}`;
+ // Add the article to the feed.
+ rssFeedXml += `
- ${rssItemTitle}${rssItemDescription}${rssItemLink}${rssItemPublishDate}
`;
+ }
+
+ rssFeedXml += ` `;
+
+ // Set the response type
+ this.res.type('text/xml');
+
+ // Return the generated RSS feed
+ return rssFeedXml;
+
+ }
+
+
+};
diff --git a/website/assets/styles/pages/articles/articles.less b/website/assets/styles/pages/articles/articles.less
index 8fff99f91c..fb282d5428 100644
--- a/website/assets/styles/pages/articles/articles.less
+++ b/website/assets/styles/pages/articles/articles.less
@@ -33,6 +33,21 @@
padding-top: 80px;
padding-bottom: 40px;
}
+ [purpose='rss-button'] {
+ padding: 4px 8px;
+ display: inline;
+ max-width: min-content;
+ color: #192147;
+ font-size: 14px;
+ text-decoration: none;
+ span::before {
+ font-family: 'FontAwesome';
+ content: '\f09e';
+ color: #192147;
+ padding-right: 8px;
+ font-size: 16px;
+ }
+ }
[purpose='articles'] {
padding-bottom: 80px;
diff --git a/website/assets/styles/pages/articles/basic-article.less b/website/assets/styles/pages/articles/basic-article.less
index 679baca9b1..c7c617982a 100644
--- a/website/assets/styles/pages/articles/basic-article.less
+++ b/website/assets/styles/pages/articles/basic-article.less
@@ -24,6 +24,22 @@
}
}
+ [purpose='rss-button'] {
+ padding: 4px 8px;
+ display: inline;
+ max-width: min-content;
+ color: #192147;
+ text-decoration: none;
+ font-size: 14px;
+ span::before {
+ vertical-align: baseline;
+ font-family: 'FontAwesome';
+ content: '\f09e';
+ color: #192147;
+ padding-right: 8px;
+ font-size: 16px;
+ }
+ }
[purpose='article-details'] {
font-size: 14px;
line-height: 20px;
diff --git a/website/config/policies.js b/website/config/policies.js
index 09f4f4b1ee..87396255e7 100644
--- a/website/config/policies.js
+++ b/website/config/policies.js
@@ -50,4 +50,5 @@ module.exports.policies = {
'view-fleet-mdm': true,
'deliver-mdm-beta-signup': true,
'deliver-apple-csr': true,
+ 'download-rss-feed': true,
};
diff --git a/website/config/routes.js b/website/config/routes.js
index 8c40c6d397..d2ebaec4d3 100644
--- a/website/config/routes.js
+++ b/website/config/routes.js
@@ -355,6 +355,10 @@ module.exports.routes = {
// XML file, which helps search engines know which pages are available on the website.
'GET /sitemap.xml': { action: 'download-sitemap' },
+ // RSS feeds
+ // =============================================================================================================
+ 'GET /rss/:categoryName': {action: 'download-rss-feed'},
+
// Potential future pages
// =============================================================================================================
// Things that are not webpages here (in the Sails app) yet, but could be in the future. For now they are just
diff --git a/website/views/pages/articles/articles.ejs b/website/views/pages/articles/articles.ejs
index 4adbf85061..4b7be05544 100644
--- a/website/views/pages/articles/articles.ejs
+++ b/website/views/pages/articles/articles.ejs
@@ -19,7 +19,10 @@
{{articleCategory}}
-
{{categoryDescription}}
+
+
{{categoryDescription}}
+
Subscribe
+
diff --git a/website/views/pages/articles/basic-article.ejs b/website/views/pages/articles/basic-article.ejs
index 4da8914fa1..a551df0a01 100644
--- a/website/views/pages/articles/basic-article.ejs
+++ b/website/views/pages/articles/basic-article.ejs
@@ -4,11 +4,14 @@
<%=thisPage.meta.articleTitle %>
{{articleSubtitle}}
-
-
-
|
-
![The author's GitHub profile picture]()
-
<%=thisPage.meta.authorFullName %>
+
+
+
+
|
+
![The author's GitHub profile picture]()
+
<%=thisPage.meta.authorFullName %>
+
+
Subscribe
<%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %>