Skip to content

Commit

Permalink
Implemented blog post pagination.
Browse files Browse the repository at this point in the history
With the new design on the blog post index,
listing all blog posts is not a viable option
anymore. This adds pagination with 15 posts per page.
  • Loading branch information
phillipj committed Nov 18, 2015
1 parent afdd8a0 commit d137a40
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 19 deletions.
8 changes: 7 additions & 1 deletion build.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const markdown = require('metalsmith-markdown')
const prism = require('metalsmith-prism')
const stylus = require('metalsmith-stylus')
const permalinks = require('metalsmith-permalinks')
const paginate = require('metalsmith-paginate')
const marked = require('marked')
const path = require('path')
const fs = require('fs')
Expand Down Expand Up @@ -112,6 +113,10 @@ function buildlocale (source, locale) {
refer: false
}
}))
.use(paginate({
perPage: 15,
path: 'blog/page'
}))
.use(markdown(markedOptions))
.use(prism())
.use(filterStylusPartials())
Expand Down Expand Up @@ -159,7 +164,8 @@ function buildlocale (source, locale) {
changeloglink: require('./scripts/helpers/changeloglink.js'),
strftime: require('./scripts/helpers/strftime.js'),
apidocslink: require('./scripts/helpers/apidocslink.js'),
summary: require('./scripts/helpers/summary.js')
summary: require('./scripts/helpers/summary.js'),
limit: require('./scripts/helpers/limit.js')
}
}))
.destination(path.join(__dirname, 'build', locale))
Expand Down
18 changes: 14 additions & 4 deletions layouts/blog-index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,31 @@

<div id="main">
<div class="container">

<ul class="blog-index">
{{#each collections.blog}}
{{#each (limit collections.blog this.pagination.end this.pagination.start)}}
{{#if title}}
<li>
<time datetime="{{ date }}">{{ strftime date "%d %b %y" }}</time>
<a href="/{{../../site.locale}}/{{ path }}/">{{ title }}</a>
<a href="/{{../site.locale}}/{{ path }}/">{{ title }}</a>
<div class="summary">
{{{ summary contents ../../site.locale path }}}
{{{ summary contents ../site.locale path }}}
<div>
</li>
{{/if}}
{{/each}}
</ul>

{{#if this.pagination}}
<nav class="pagination">
{{#if this.pagination.prev}}
<a href="/{{site.locale}}/{{this.pagination.prev.path}}">&lt; Prev</a>
{{/if}}

{{#if this.pagination.next}}
<a href="/{{site.locale}}/{{this.pagination.next.path}}">Next &gt;</a>
{{/if}}
</nav>
{{/if}}
</div>
</div>

Expand Down
1 change: 1 addition & 0 deletions locale/en/blog/index.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
---
layout: blog-index.hbs
paginate: blog
---
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"metalsmith-layouts": "1.4.2",
"metalsmith-markdown": "0.2.1",
"metalsmith-metadata": "0.0.2",
"metalsmith-paginate": "0.3.0",
"metalsmith-permalinks": "0.4.0",
"metalsmith-prism": "2.1.1",
"metalsmith-stylus": "1.0.0",
Expand Down
5 changes: 5 additions & 0 deletions scripts/helpers/limit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict'

module.exports = (collection, limit, start) => {
return collection.slice(start, limit + 1)
}
49 changes: 35 additions & 14 deletions scripts/helpers/summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,46 @@

const cheerio = require('cheerio')

const SUMMARY_LENGHT = 400
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/<html>, <head> and <body> etc)
* wrapped around the actual blog contents :(
*/

module.exports = function (contents, locale, path) {
let $ = cheerio.load(contents)
const $ = cheerio.load(contents)
const $body = $('body')
const hasBody = $body.length > 0
const $elements = hasBody ? $body.find('article > *') : $('*')

let summary = ''

$('*').each((i, elem) => {
if (summary.length > SUMMARY_LENGHT) {
summary += `<p><a href='/${locale}/${path}/'>Read more...</a></p>`
return false
}

if (elem.parent) {
return
}

summary += $.html(elem)
})
$elements
.not((i, elem) => IGNORE_SELECTORS.some((selector) => $(elem).is(selector)))
.each((i, elem) => {
if (summary.length > SUMMARY_MAX_LENGTH) {
summary += `<p><a href='/${locale}/${path}/'>Read more...</a></p>`
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
}

0 comments on commit d137a40

Please sign in to comment.