diff --git a/website/api/controllers/articles/view-articles.js b/website/api/controllers/articles/view-articles.js index b7f11213eb..a8396e18f2 100644 --- a/website/api/controllers/articles/view-articles.js +++ b/website/api/controllers/articles/view-articles.js @@ -26,12 +26,13 @@ module.exports = { }, - fn: async function ({category}) { + fn: async function () { if (!_.isObject(sails.config.builtStaticContent) || !_.isArray(sails.config.builtStaticContent.markdownPages) || !sails.config.builtStaticContent.compiledPagePartialsAppPath) { throw {badConfig: 'builtStaticContent.markdownPages'}; } let articles = []; + let category = this.req.path.split('/')[1]; if (category === 'articles') { // If the category is `/articles` we'll show all articles articles = sails.config.builtStaticContent.markdownPages.filter((page)=>{ @@ -39,8 +40,6 @@ module.exports = { return page; } }); - // setting the category to all - category = 'all'; } else { // if the user navigates to a URL for a specific category, we'll only display articles in that category articles = sails.config.builtStaticContent.markdownPages.filter((page)=>{ @@ -96,6 +95,10 @@ module.exports = { pageTitleForMeta = 'Podcasts'; pageDescriptionForMeta = 'Listen to the Future of Device Management podcast.'; break; + case 'articles': + pageTitleForMeta = 'Articles'; + pageDescriptionForMeta = 'Read the latest articles from the Fleet team and community.'; + break; } diff --git a/website/api/controllers/articles/view-basic-article.js b/website/api/controllers/articles/view-basic-article.js index 6648cebc58..19f977bcd9 100644 --- a/website/api/controllers/articles/view-basic-article.js +++ b/website/api/controllers/articles/view-basic-article.js @@ -34,7 +34,7 @@ module.exports = { } // Serve appropriate page content. - let thisPage = _.find(sails.config.builtStaticContent.markdownPages, { url: '/' + pageUrlSuffix }); + let thisPage = _.find(sails.config.builtStaticContent.markdownPages, { url: this.req.path }); if (!thisPage) {// If there's no EXACTLY matching content page, try a revised version of the URL suffix that's lowercase, with all slashes deduped, and any leading or trailing slash removed (leading slashes are only possible if this is a regex, rather than "/*" route) let revisedPageUrlSuffix = pageUrlSuffix.toLowerCase().replace(/\/+/g, '/').replace(/^\/+/,'').replace(/\/+$/,''); thisPage = _.find(sails.config.builtStaticContent.markdownPages, { url: '/' + revisedPageUrlSuffix }); @@ -44,9 +44,6 @@ module.exports = { throw 'notFound'; } } - - 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. @@ -61,13 +58,23 @@ module.exports = { pageDescriptionForMeta = _.trimRight(thisPage.meta.articleTitle, '.') + ' by ' + thisPage.meta.authorFullName; }//fi + let articleCategorySlug = this.req.path.split('/')[1]; + // console.log(articleCategorySlug); + let categoryFriendlyNamesByCategorySlug = { + 'success-stories': 'Success stories', + 'releases': 'Releases', + 'guides': 'Guides', + 'securing': 'Security articles', + 'engineering': 'Engineering articles', + 'announcements': 'Announcements', + 'podcasts': 'Podcasts', + 'report': 'Reports', + }; + let categoryFriendlyName = categoryFriendlyNamesByCategorySlug[articleCategorySlug]; // Set a currentSection variable for the website header based on how the articles category page is linked to in the header navigation dropdown menus. let currentSection; - if(articleCategorySlug === 'success-stories'){ - // If the article is in the 'device-management' category, highlight the "Platform" dropdown. - currentSection = 'platform'; - } else if(_.contains(['deploy','guides','releases'], articleCategorySlug)) { - // If the articleCategorySlug is deploy, guides, or release, highlight the "Documentation" dropdown. + if(['guides','releases'].includes(articleCategorySlug)) { + // If the articleCategorySlug is guides, or releases, highlight the "Documentation" dropdown. currentSection = 'documentation'; } else { // If the article is in any other category, highlight the "Community" dropdown. @@ -85,6 +92,7 @@ module.exports = { pageDescriptionForMeta, pageImageForMeta: thisPage.meta.articleImageUrl || undefined, articleCategorySlug, + categoryFriendlyName, currentSection, algoliaPublicKey: sails.config.custom.algoliaPublicKey, }; @@ -92,4 +100,5 @@ module.exports = { } + }; diff --git a/website/api/hooks/custom/index.js b/website/api/hooks/custom/index.js index 5a46166252..0e4f592f05 100644 --- a/website/api/hooks/custom/index.js +++ b/website/api/hooks/custom/index.js @@ -70,11 +70,6 @@ will be disabled and/or hidden in the UI. // This will determine whether or not to enable various billing features. sails.config.custom.enableBillingFeatures = !isMissingStripeConfig; - - // Override the default sails.LOOKS_LIKE_ASSET_RX with a regex that does not match paths starting with '/release/'. - // Otherwise, our release blog posts are treated as assets because they contain periods in their URL (e.g., fleetdm.com/releases/fleet-4.29.0) - sails.LOOKS_LIKE_ASSET_RX = /^(?!\/releases\/|\/announcements\/|\/success-stories\/|\/securing\/|\/engineering\/|\/podcasts\/*$)[^?]*\/[^?\/]+\.[^?\/]+(\?.*)?$/; - // After "sails-hook-organics" finishes initializing, configure Stripe // and Sendgrid packs with any available credentials. sails.after('hook:organics:loaded', ()=>{ diff --git a/website/assets/js/pages/articles/articles.page.js b/website/assets/js/pages/articles/articles.page.js index cf15625714..a24be4a2d8 100644 --- a/website/assets/js/pages/articles/articles.page.js +++ b/website/assets/js/pages/articles/articles.page.js @@ -50,7 +50,7 @@ parasails.registerPage('articles', { this.articleCategory = 'Reports'; this.categoryDescription = ''; break; - case 'all': + case 'articles': this.articleCategory = 'Articles'; this.categoryDescription = 'Read the latest articles from the Fleet team and community.'; break; diff --git a/website/config/routes.js b/website/config/routes.js index 503f9f5c7f..6293d097c4 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -73,15 +73,142 @@ module.exports.routes = { } }, - 'r|^/((success-stories|securing|releases|engineering|guides|announcements|podcasts|report|deploy)/(.+))$|': { - skipAssets: false, - action: 'articles/view-basic-article',// Meta title and description set in view action - },// Handles /device-management/foo, /securing/foo, /releases/foo, /engineering/foo, /guides/foo, /announcements/foo, /deploy/foo, /podcasts/foo, /report/foo - - 'r|^/((success-stories|securing|releases|engineering|guides|announcements|articles|podcasts|report|deploy))/*$|category': { + 'GET /articles': { skipAssets: false, action: 'articles/view-articles',// Meta title and description set in view action - },// Handles the article landing page /articles, and the article cateogry pages (e.g. /device-management, /securing, /releases, etc) + locals: { + currentSection: 'community', + } + }, + + 'GET /success-stories': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /success-stories/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /success-stores/foo + + 'GET /securing': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /securing/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /securing/foo + + 'GET /releases': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'documentation', + } + }, + + 'GET /releases/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'documentation', + } + },// handles /releases/foo + + 'GET /guides': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'documentation', + } + }, + + 'GET /guides/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'documentation', + } + },// handles /guides/foo + + 'GET /announcements': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /announcements/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /announcements/foo + + 'GET /podcasts': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /podcasts/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /podcasts/foo + + 'GET /engineering': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /engineering/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /engineering/foo + + 'GET /report': { + skipAssets: false, + action: 'articles/view-articles',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + }, + + 'GET /report/*': { + skipAssets: false, + action: 'articles/view-basic-article',// Meta title and description set in view action + locals: { + currentSection: 'community', + } + },// handles /engineering/foo + 'GET /docs/?*': { skipAssets: false, @@ -520,6 +647,81 @@ module.exports.routes = { 'GET /guides/how-to-uninstall-osquery': (req,res)=> { return res.redirect(301, '/guides/how-to-uninstall-fleetd');}, 'GET /guides/sysadmin-diaries-lost-device': (req,res)=> { return res.redirect(301, '/guides/lock-wipe-hosts');}, + // Release note article redirects. + 'GET /releases/fleet-3.10.0': '/releases/fleet-3-10-0', + 'GET /releases/fleet-3.12.0': '/releases/fleet-3-12-0', + 'GET /releases/fleet-3.13.0': '/releases/fleet-3-13-0', + 'GET /releases/fleet-3.5.0': '/releases/fleet-3-5-0', + 'GET /releases/fleet-3.6.0': '/releases/fleet-3-6-0', + 'GET /releases/fleet-3.7.1': '/releases/fleet-3-7-1', + 'GET /releases/fleet-3.8.0': '/releases/fleet-3-8-0', + 'GET /releases/fleet-3.9.0': '/releases/fleet-3-9-0', + 'GET /releases/fleet-4.0.0': '/releases/fleet-4-0-0', + 'GET /releases/fleet-4.1.0': '/releases/fleet-4-1-0', + 'GET /releases/fleet-4.10.0': '/releases/fleet-4-10-0', + 'GET /releases/fleet-4.12.0': '/releases/fleet-4-12-0', + 'GET /releases/fleet-4.11.0': '/releases/fleet-4-11-0', + 'GET /releases/fleet-4.13.0': '/releases/fleet-4-13-0', + 'GET /releases/fleet-4.15.0': '/releases/fleet-4-15-0', + 'GET /releases/fleet-3.11.0': '/releases/fleet-3-11-0', + 'GET /releases/fleet-4.16.0': '/releases/fleet-4-16-0', + 'GET /releases/fleet-4.17.0': '/releases/fleet-4-17-0', + 'GET /releases/fleet-4.18.0': '/releases/fleet-4-18-0', + 'GET /releases/fleet-4.19.0': '/releases/fleet-4-19-0', + 'GET /releases/fleet-4.2.0': '/releases/fleet-4-2-0', + 'GET /releases/fleet-4.21.0': '/releases/fleet-4-21-0', + 'GET /releases/fleet-4.14.0': '/releases/fleet-4-14-0', + 'GET /releases/fleet-4.22.0': '/releases/fleet-4-22-0', + 'GET /releases/fleet-4.20.0': '/releases/fleet-4-20-0', + 'GET /releases/fleet-4.23.0': '/releases/fleet-4-23-0', + 'GET /releases/fleet-4.24.0': '/releases/fleet-4-24-0', + 'GET /releases/fleet-4.25.0': '/releases/fleet-4-25-0', + 'GET /releases/fleet-4.27.0': '/releases/fleet-4-27-0', + 'GET /releases/fleet-4.26.0': '/releases/fleet-4-26-0', + 'GET /releases/fleet-4.28.0': '/releases/fleet-4-28-0', + 'GET /releases/fleet-4.29.0': '/releases/fleet-4-29-0', + 'GET /releases/fleet-4.30.0': '/releases/fleet-4-30-0', + 'GET /releases/fleet-4.31.0': '/releases/fleet-4-31-0', + 'GET /releases/fleet-4.3.0': '/releases/fleet-4-3-0', + 'GET /releases/fleet-4.32.0': '/releases/fleet-4-32-0', + 'GET /releases/fleet-4.33.0': '/releases/fleet-4-33-0', + 'GET /releases/fleet-4.34.0': '/releases/fleet-4-34-0', + 'GET /releases/fleet-4.36.0': '/releases/fleet-4-36-0', + 'GET /releases/fleet-4.38.0': '/releases/fleet-4-38-0', + 'GET /releases/fleet-4.39.0': '/releases/fleet-4-39-0', + 'GET /releases/fleet-4.35.0': '/releases/fleet-4-35-0', + 'GET /releases/fleet-4.4.0': '/releases/fleet-4-4-0', + 'GET /releases/fleet-4.37.0': '/releases/fleet-4-37-0', + 'GET /releases/fleet-4.40.0': '/releases/fleet-4-40-0', + 'GET /releases/fleet-4.42.0': '/releases/fleet-4-42-0', + 'GET /releases/fleet-4.43.0': '/releases/fleet-4-43-0', + 'GET /releases/fleet-4.44.0': '/releases/fleet-4-44-0', + 'GET /releases/fleet-4.41.0': '/releases/fleet-4-41-0', + 'GET /releases/fleet-4.45.0': '/releases/fleet-4-45-0', + 'GET /releases/fleet-4.46.0': '/releases/fleet-4-46-0', + 'GET /releases/fleet-4.47.0': '/releases/fleet-4-47-0', + 'GET /releases/fleet-4.49.0': '/releases/fleet-4-49-0', + 'GET /releases/fleet-4.5.0': '/releases/fleet-4-5-0', + 'GET /releases/fleet-4.50.0': '/releases/fleet-4-50-0', + 'GET /releases/fleet-4.51.0': '/releases/fleet-4-51-0', + 'GET /releases/fleet-4.48.0': '/releases/fleet-4-48-0', + 'GET /releases/fleet-4.53.0': '/releases/fleet-4-53-0', + 'GET /releases/fleet-4.55.0': '/releases/fleet-4-55-0', + 'GET /releases/fleet-4.56.0': '/releases/fleet-4-56-0', + 'GET /releases/fleet-4.54.0': '/releases/fleet-4-54-0', + 'GET /releases/fleet-4.58.0': '/releases/fleet-4-58-0', + 'GET /releases/fleet-4.59.0': '/releases/fleet-4-59-0', + 'GET /releases/fleet-4.57.0': '/releases/fleet-4-57-0', + 'GET /releases/fleet-4.6.0': '/releases/fleet-4-6-0', + 'GET /releases/fleet-4.60.0': '/releases/fleet-4-60-0', + 'GET /releases/fleet-4.7.0': '/releases/fleet-4-7-0', + 'GET /releases/fleet-4.8.0': '/releases/fleet-4-8-0', + 'GET /releases/fleet-4.61.0': '/releases/fleet-4-61-0', + 'GET /releases/fleet-4.9.0': '/releases/fleet-4-9-0', + 'GET /announcements/nvd-api-2.0': '/announcements/nvd-api-2-0', + 'GET /releases/osquery-5.11.0': '/releases/osquery-5-11-0', + 'GET /releases/osquery-5.8.1': '/releases/osquery-5-8-1', + // ╔╦╗╦╔═╗╔═╗ ╦═╗╔═╗╔╦╗╦╦═╗╔═╗╔═╗╔╦╗╔═╗ ┬ ╔╦╗╔═╗╦ ╦╔╗╔╦ ╔═╗╔═╗╔╦╗╔═╗ // ║║║║╚═╗║ ╠╦╝║╣ ║║║╠╦╝║╣ ║ ║ ╚═╗ ┌┼─ ║║║ ║║║║║║║║ ║ ║╠═╣ ║║╚═╗ // ╩ ╩╩╚═╝╚═╝ ╩╚═╚═╝═╩╝╩╩╚═╚═╝╚═╝ ╩ ╚═╝ └┘ ═╩╝╚═╝╚╩╝╝╚╝╩═╝╚═╝╩ ╩═╩╝╚═╝ diff --git a/website/scripts/build-static-content.js b/website/scripts/build-static-content.js index d11cc4274f..0c0c7dff2d 100644 --- a/website/scripts/build-static-content.js +++ b/website/scripts/build-static-content.js @@ -535,7 +535,7 @@ module.exports = { rootRelativeUrlPath = ( '/' + (encodeURIComponent(embeddedMetadata.category === 'success stories' ? 'success-stories' : embeddedMetadata.category === 'security' ? 'securing' : embeddedMetadata.category)) + '/' + - (pageUnextensionedUnwhitespacedLowercasedRelPath.split(/\//).map((fileOrFolderName) => encodeURIComponent(fileOrFolderName.replace(/^[0-9]+[\-]+/,''))).join('/')) + (pageUnextensionedUnwhitespacedLowercasedRelPath.split(/\//).map((fileOrFolderName) => encodeURIComponent(fileOrFolderName.replace(/^[0-9]+[\-]+/,'').replace(/\./g, '-'))).join('/')) ); } diff --git a/website/views/pages/articles/basic-article.ejs b/website/views/pages/articles/basic-article.ejs index a469250b63..c951994580 100644 --- a/website/views/pages/articles/basic-article.ejs +++ b/website/views/pages/articles/basic-article.ejs @@ -3,7 +3,7 @@
- {{articleCategorySlug}}/ + {{categoryFriendlyName}}/
{{thisPage.meta.articleTitle}}