diff --git a/build.js b/build.js
index a75d519c76f2b..a16c4d21f6abb 100755
--- a/build.js
+++ b/build.js
@@ -14,6 +14,7 @@ const markdown = require('metalsmith-markdown')
const prism = require('metalsmith-prism')
const stylus = require('metalsmith-stylus')
const permalinks = require('metalsmith-permalinks')
+const pagination = require('metalsmith-yearly-pagination')
const marked = require('marked')
const path = require('path')
const fs = require('fs')
@@ -126,6 +127,13 @@ function buildlocale (source, locale) {
refer: false
}
}))
+ .use(pagination({
+ path: 'blog/year',
+ iteratee: (post, idx) => ({
+ post,
+ displaySummary: idx < 10
+ })
+ }))
.use(markdown(markedOptions))
.use(githubLinks({ locale: locale }))
.use(prism())
@@ -182,7 +190,8 @@ function buildlocale (source, locale) {
changeloglink: require('./scripts/helpers/changeloglink.js'),
strftime: require('./scripts/helpers/strftime.js'),
apidocslink: require('./scripts/helpers/apidocslink.js'),
- majorapidocslink: require('./scripts/helpers/majorapidocslink.js')
+ majorapidocslink: require('./scripts/helpers/majorapidocslink.js'),
+ summary: require('./scripts/helpers/summary.js')
}
}))
// Pipes the generated files into their respective subdirectory in the build
diff --git a/layouts/blog-index.hbs b/layouts/blog-index.hbs
index f284be248f364..305e97b34007b 100644
--- a/layouts/blog-index.hbs
+++ b/layouts/blog-index.hbs
@@ -1,5 +1,5 @@
-
+
{{> html-head }}
@@ -7,18 +7,34 @@
+
News from {{ pagination.year }}
- {{#each collections.blog}}
- {{#if title}}
-
- {{ strftime date "%d %b %y" }}
- {{ title }}
-
- {{/if}}
+ {{#each pagination.posts}}
+
+ {{ strftime post.date "%d %b" }}
+ {{ post.title }}
+
+ {{#if displaySummary}}
+
+ {{{ summary post.contents ../site.locale post.path }}}
+
+ {{/if}}
+
{{/each}}
+ {{#if pagination}}
+
+ {{/if}}
diff --git a/layouts/css/page-modules/_blog-index.styl b/layouts/css/page-modules/_blog-index.styl
index ab6972c2513e8..3713b24edc19f 100644
--- a/layouts/css/page-modules/_blog-index.styl
+++ b/layouts/css/page-modules/_blog-index.styl
@@ -1,4 +1,11 @@
.blog-index
+ list-style none
+ padding 0
+
time
margin-right 1em
color $light-gray
+
+ .summary
+ margin-left 1em
+ font-size: 75%
diff --git a/locale/en/blog/index.md b/locale/en/blog/index.md
index b1a0378e971ad..24248de1867d0 100644
--- a/locale/en/blog/index.md
+++ b/locale/en/blog/index.md
@@ -1,3 +1,4 @@
---
layout: blog-index.hbs
+paginate: blog
---
diff --git a/package.json b/package.json
index 4a5566fddb96d..b611c0ab724c6 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"dependencies": {
"autoprefixer-stylus": "0.8.1",
"changelog-url": "1.0.0",
+ "cheerio": "0.19.0",
"chokidar": "1.2.0",
"handlebars": "4.0.4",
"html-to-text": "^1.5.0",
@@ -42,6 +43,7 @@
"metalsmith-permalinks": "0.4.0",
"metalsmith-prism": "2.1.1",
"metalsmith-stylus": "1.0.0",
+ "metalsmith-yearly-pagination": "2.0.0",
"ncp": "2.0.0",
"node-geocoder": "^3.4.1",
"node-version-data": "1.0.0",
diff --git a/scripts/helpers/summary.js b/scripts/helpers/summary.js
new file mode 100644
index 0000000000000..c1222e72107d8
--- /dev/null
+++ b/scripts/helpers/summary.js
@@ -0,0 +1,47 @@
+'use strict'
+
+const cheerio = require('cheerio')
+
+const SUMMARY_MAX_LENGTH = 300
+const IGNORE_SELECTORS = ['.blogpost-header', '.anchor', 'h1', 'h2', 'h3', 'blockquote']
+
+/**
+ * Due to the nature of metalsmith and
+ * how the metalsmith-paginate plugin operates,
+ * this helper has to handle two different types of
+ * HTML contents:
+ * - clean blog posts converted from markdown to HTML,
+ * seen on the first page of blog posts
+ * - the remaining paginated pages has gone
+ * through the handlebars process and therefore has the
+ * entire page layout (w/, and etc)
+ * wrapped around the actual blog contents :(
+ */
+
+module.exports = function (contents, locale, path) {
+ const $ = cheerio.load(contents)
+ const $body = $('body')
+ const hasBody = $body.length > 0
+ const $elements = hasBody ? $body.find('article > *') : $('*')
+
+ let summary = ''
+
+ $elements
+ .not((i, elem) => IGNORE_SELECTORS.some((selector) => $(elem).is(selector)))
+ .each((i, elem) => {
+ if (summary.length > SUMMARY_MAX_LENGTH) {
+ summary += `Read more...
`
+ return false
+ }
+
+ // dont re-add nested elements when extracting summary
+ // from blog posts not contained in a complete HTML document
+ if (!hasBody && elem.parent) {
+ return
+ }
+
+ summary += $.html(elem)
+ })
+
+ return summary
+}