diff --git a/lib/__tests__/build-files.tests.js b/lib/__tests__/build-files.test.js similarity index 100% rename from lib/__tests__/build-files.tests.js rename to lib/__tests__/build-files.test.js diff --git a/lib/core/BlogPost.js b/lib/core/BlogPost.js index 7a8ba07644..5386946d82 100644 --- a/lib/core/BlogPost.js +++ b/lib/core/BlogPost.js @@ -8,32 +8,32 @@ const MarkdownBlock = require('./MarkdownBlock.js'); const React = require('react'); +const utils = require('./utils'); + // inner blog component for the article itself, without sidebar/header/footer class BlogPost extends React.Component { renderContent() { - let content = this.props.content; - let hasSplit = false; - if (content.split('').length > 1) { - hasSplit = ( -
- - Read More - -
- ); - } if (this.props.truncate) { - content = content.split('')[0]; return (
- {content} - {hasSplit} + + {utils.extractBlogPostBeforeTruncate(this.props.content)} + + {utils.blogPostHasTruncateMarker(this.props.content) && ( +
+ + Read More + +
+ )}
); } - return {content}; + return {this.props.content}; } renderAuthorPhoto() { diff --git a/lib/core/__tests__/__fixtures__/blog-post-with-truncate.md b/lib/core/__tests__/__fixtures__/blog-post-with-truncate.md new file mode 100644 index 0000000000..cceae720f6 --- /dev/null +++ b/lib/core/__tests__/__fixtures__/blog-post-with-truncate.md @@ -0,0 +1,15 @@ +--- +title: Truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + + + +But anything from here on down will not be. + +Not this. + +Or this. diff --git a/lib/core/__tests__/__fixtures__/blog-post-without-truncate.md b/lib/core/__tests__/__fixtures__/blog-post-without-truncate.md new file mode 100644 index 0000000000..2232756672 --- /dev/null +++ b/lib/core/__tests__/__fixtures__/blog-post-without-truncate.md @@ -0,0 +1,13 @@ +--- +title: Non-truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + +And anything from here on down will still be. + +And this. + +And this too. diff --git a/lib/core/__tests__/__snapshots__/anchors.tests.js.snap b/lib/core/__tests__/__snapshots__/anchors.test.js.snap similarity index 100% rename from lib/core/__tests__/__snapshots__/anchors.tests.js.snap rename to lib/core/__tests__/__snapshots__/anchors.test.js.snap diff --git a/lib/core/__tests__/__snapshots__/getTOC.tests.js.snap b/lib/core/__tests__/__snapshots__/getTOC.test.js.snap similarity index 100% rename from lib/core/__tests__/__snapshots__/getTOC.tests.js.snap rename to lib/core/__tests__/__snapshots__/getTOC.test.js.snap diff --git a/lib/core/__tests__/__snapshots__/utils.test.js.snap b/lib/core/__tests__/__snapshots__/utils.test.js.snap new file mode 100644 index 0000000000..a7eb240a4f --- /dev/null +++ b/lib/core/__tests__/__snapshots__/utils.test.js.snap @@ -0,0 +1,66 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`utils extractBlogPostBeforeTruncate 1`] = ` +"--- +title: Truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + +" +`; + +exports[`utils extractBlogPostBeforeTruncate 2`] = ` +"--- +title: Non-truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + +And anything from here on down will still be. + +And this. + +And this too. +" +`; + +exports[`utils extractBlogPostSummary 1`] = ` +"--- +title: Truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + + + +But anything from here on down will not be. + +Not this. + +Or this. +" +`; + +exports[`utils extractBlogPostSummary 2`] = ` +"--- +title: Non-truncation Example +--- + +All this will be part of the blog post summary. + +Even this. + +And anything from here on down will still be. + +And this. + +And this too. +" +`; diff --git a/lib/core/__tests__/anchors.tests.js b/lib/core/__tests__/anchors.test.js similarity index 100% rename from lib/core/__tests__/anchors.tests.js rename to lib/core/__tests__/anchors.test.js diff --git a/lib/core/__tests__/getTOC.tests.js b/lib/core/__tests__/getTOC.test.js similarity index 100% rename from lib/core/__tests__/getTOC.tests.js rename to lib/core/__tests__/getTOC.test.js diff --git a/lib/core/__tests__/toSlug.tests.js b/lib/core/__tests__/toSlug.test.js similarity index 100% rename from lib/core/__tests__/toSlug.tests.js rename to lib/core/__tests__/toSlug.test.js diff --git a/lib/core/__tests__/utils.test.js b/lib/core/__tests__/utils.test.js new file mode 100644 index 0000000000..fcd69112e7 --- /dev/null +++ b/lib/core/__tests__/utils.test.js @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const path = require('path'); +const utils = require('../utils'); +const readFileSync = require('fs').readFileSync; + +const blogPostWithTruncateContents = readFileSync( + path.join(__dirname, '__fixtures__', 'blog-post-with-truncate.md'), + 'utf-8' +); + +const blogPostWithoutTruncateContents = readFileSync( + path.join(__dirname, '__fixtures__', 'blog-post-without-truncate.md'), + 'utf-8' +); + +describe('utils', () => { + test('blogPostHasTruncateMarker', () => { + expect(utils.blogPostHasTruncateMarker(blogPostWithTruncateContents)).toBe( + true + ); + expect( + utils.blogPostHasTruncateMarker(blogPostWithoutTruncateContents) + ).toBe(false); + }); + + test('extractBlogPostBeforeTruncate', () => { + expect( + utils.extractBlogPostBeforeTruncate(blogPostWithTruncateContents) + ).toMatchSnapshot(); + expect( + utils.extractBlogPostBeforeTruncate(blogPostWithoutTruncateContents) + ).toMatchSnapshot(); + }); + + test('extractBlogPostSummary', () => { + expect( + utils.extractBlogPostSummary(blogPostWithTruncateContents) + ).toMatchSnapshot(); + expect( + utils.extractBlogPostSummary(blogPostWithoutTruncateContents) + ).toMatchSnapshot(); + }); +}); diff --git a/lib/core/utils.js b/lib/core/utils.js new file mode 100644 index 0000000000..4d880763b9 --- /dev/null +++ b/lib/core/utils.js @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const BLOG_POST_SUMMARY_LENGTH = 250; +const TRUNCATE_MARKER = //; + +function blogPostHasTruncateMarker(content) { + return TRUNCATE_MARKER.test(content); +} + +function extractBlogPostBeforeTruncate(content) { + return content.split(TRUNCATE_MARKER)[0]; +} + +function extractBlogPostSummary(content) { + return content.substring(0, BLOG_POST_SUMMARY_LENGTH); +} + +module.exports = { + blogPostHasTruncateMarker, + extractBlogPostBeforeTruncate, + extractBlogPostSummary, +}; diff --git a/lib/server/feed.js b/lib/server/feed.js index faeea4c191..bb57f490a7 100644 --- a/lib/server/feed.js +++ b/lib/server/feed.js @@ -19,6 +19,7 @@ const blogFolder = path.resolve('../blog/'); const blogRootURL = siteConfig.url + siteConfig.baseUrl + 'blog'; const siteImageURL = siteConfig.url + siteConfig.baseUrl + siteConfig.headerIcon; +const utils = require('../core/utils'); const renderMarkdown = require('../core/renderMarkdown.js'); @@ -56,18 +57,9 @@ module.exports = function(type) { MetadataBlog.forEach(post => { const url = blogRootURL + '/' + post.path; - let content = ''; - if (post.content.indexOf('') == -1) { - content = post.content.trim().substring(0, 250); - } else { - let contentArr = post.content.split(''); - if (contentArr.length > 0) { - content = contentArr[0]; - } - } - - content = renderMarkdown(content); - + const content = utils.blogPostHasTruncateMarker(post.content) + ? utils.extractBlogPostBeforeTruncate(post.content) + : utils.extractBlogPostSummary(post.content.trim()); feed.addItem({ title: post.title, link: url, @@ -78,7 +70,7 @@ module.exports = function(type) { }, ], date: new Date(post.date), - description: content, + description: renderMarkdown(content), }); });