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 = (
-
- );
- }
if (this.props.truncate) {
- content = content.split('')[0];
return (
- {content}
- {hasSplit}
+
+ {utils.extractBlogPostBeforeTruncate(this.props.content)}
+
+ {utils.blogPostHasTruncateMarker(this.props.content) && (
+
+ )}
);
}
- 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),
});
});