metalsmith-sectioned-blog-pagination
v1.4.0
Published
Metalsmith plugin that generates paginated blog landing pages from a main blog template
Maintainers
Readme
Metalsmith Sectioned Blog Pagination
Metalsmith plugin that generates metadata for blog pagination for pages built with a modular page building paradigm.
Features
- ESM and CommonJS support:
- ESM:
import prism from 'metalsmith-prism' - CommonJS:
const prism = require('metalsmith-prism')
- ESM:
Requirements
- Node.js >= 18.0.0
- Metalsmith >= 2.6.0
Installation
npm install metalsmith-sectioned-blog-paginationUsage
Pass options to metalsmith-sectioned-blog-pagination in metalsmith.use :
The plugin must be used before the Markdown, Permalinks and Layouts plugins.
Metalsmith( __dirname )
.use(collections({
blog: {
pattern: "blog/*.md",
sortBy: "date",
reverse: true,
limit: 50,
},
}))
.use(blogPages({
"pagesPerPage": 12, // Number of blog posts per page
"blogDirectory": "blog/", // Directory containing your blog posts
"mainTemplate": "blog.md" // Main blog template file (default: "blog.md")
}))
.use(markdown())
.use(permalinks())
.use(layouts())
...Options
| Option | Type | Default | Description |
| ---------------- | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| pagesPerPage | number | 6 | Number of blog posts to display per page |
| blogDirectory | string | 'blog/' | Directory containing blog post files (with trailing slash) |
| mainTemplate | string | 'blog.md' | Main blog template file to use as template for pagination |
| collectionName | string | none | Name of a @metalsmith/collections collection to count posts from, instead of scanning blogDirectory. Use this when the directory holds files that are not collection members (category landing pages, generated pages), which would otherwise inflate the page count. Requires the collections plugin to run first. |
Section frontmatter
The main template must contain a section marked hasPagingParams: true. That is all the frontmatter
needs; the plugin creates a pagingParams object on that section and fills it in at build time:
sections:
- sectionType: blog-list
hasPagingParams: trueAfter the build the section carries:
pagingParams:
numberOfBlogs: 42 # Total posts in the collection
numberOfPages: 7 # Total pagination pages
pageLength: 6 # Posts per page (pagesPerPage)
pageStart: 0 # Index of this page's first post
pageNumber: 1 # This page's number, 1-indexedDeclaring placeholder keys in the frontmatter still works: any of the five keys that already exist
anywhere in the section are updated in place, and only the missing ones are added under
pagingParams. (Before v1.4.0 the placeholders were required — a section with only
hasPagingParams: true was silently left without paging values.)
Examples
Basic Blog Pagination
Create paginated blog pages with 10 posts per page:
metalsmith
.use(
collections({
blog: {
pattern: 'blog/*.md',
sortBy: 'date',
reverse: true,
},
})
)
.use(
blogPages({
pagesPerPage: 10,
blogDirectory: 'blog/',
mainTemplate: 'blog.md',
})
);Multiple Blog Sections
For sites with multiple blog sections, run the plugin multiple times:
metalsmith
// Tech blog section
.use(
collections({
techBlog: {
pattern: 'tech/*.md',
sortBy: 'date',
reverse: true,
},
})
)
.use(
blogPages({
pagesPerPage: 8,
blogDirectory: 'tech/',
mainTemplate: 'tech-blog.md',
})
)
// Personal blog section
.use(
collections({
personalBlog: {
pattern: 'personal/*.md',
sortBy: 'date',
reverse: true,
},
})
)
.use(
blogPages({
pagesPerPage: 5,
blogDirectory: 'personal/',
mainTemplate: 'personal-blog.md',
})
);Custom Blog Directory Structure
Use a nested directory structure for your blog:
metalsmith.use(
blogPages({
pagesPerPage: 15,
blogDirectory: 'content/articles/',
mainTemplate: 'articles.md',
})
);
// This will create: /content/articles/, /content/articles/2/, etc.During the build process, the plugin will create a set of blog landing pages with the specified
number of blog posts per page, e.g. /blog/, /blog/2, /blog/3... In a Nunjucks template, a
pager would be constructed like this:
<ul class="blogs-pagination">
{% for i in range(0, params.numberOfPages) -%}
<li {% if ((i + 1)="" ="params.pageNumber)" %}class="active" {% endif %}>
{% if i == 0 %}
<a href="/blog/">1</a>
{% else %}
<a href="/blog/{{ i + 1 }}/">{{ i + 1 }}</a>
{% endif %}
</li>
{%- endfor %}
</ul>And complete template implementation in Nunjucks for such a blog landing page can be viewed here. And here is an example of an implementation.
Debug
To enable debug logs, set the DEBUG environment variable to
metalsmith-sectioned-blog-pagination:
Linux/Mac:
DEBUG=metalsmith-sectioned-blog-paginationWindows:
set DEBUG=metalsmith-sectioned-blog-paginationCLI usage
To use this plugin with the Metalsmith CLI, add metalsmith-sectioned-blog-pagination to the
plugins key in your metalsmith.json file:
{
"plugins": [
{
"metalsmith-sectioned-blog-pagination": {
"pagesPerPage": 12,
"blogDirectory": "blog/"
}
}
]
}Test Coverage
This project maintains high statement and line coverage for the source code. Coverage is verified during the release process using the c8 coverage tool.
