Previous and Next for Next js
So I wrote a node script to update my previous and next for every blog entry and then it would write it out in markdown as part of the header, so it would look like this:
---
title: "Practice does not make perfect"
date: "2018-04-15"
next: "simplicity-over-complex"
prev: "building-teams-and-careers"
---
And it would sort my posts by date, so it would automatically find the next one and previous appropriately. And also, it would need to not show previous if on the first and not show next if on the last, that was a little react variable code, super simple.
const prevLink = postData.prev ? (<Link href="/posts/${postData.prev}" as={`/posts/${postData.prev}`}>
Previous
</Link>) : ''
const nextLink = postData.next ? (<Link href="/posts/${postData.next}" as={`/posts/${postData.next}`}>
Next
</Link>) : ''
But it was fun creating something that will change the prev/next if the date is different. I'll write more about it in a bit, but wanted to get this down. I used the NextJS blog functions in node, and then parsed it using greymatter like they did.
Ok, I'll do it now.
var fs = require('fs')
var path = require('path')
var matter = require('gray-matter')
const postsDirectory = path.join(process.cwd(), 'source')
const outputDirectory = path.join(process.cwd(),'posts')
function getSortedPostsData() {
// Get file names under /posts
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
// Remove ".md" from file name to get id
const id = fileName.replace(/\.md$/, '')
// Read markdown file as string
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
const contentData = matterResult.content
// Combine the data with the id
return {
id,
contentData,
...matterResult.data
}
})
// Sort posts by date
return allPostsData.sort((a, b) => {
if (a.date < b.date) {
return 1
} else {
return -1
}
})
}
function writeNewData(data){
data.map(item => {
const outputFile = path.join(outputDirectory, item.id + '.md')
nextIndex = item.index - 1
prevIndex = item.index + 1
output = ''
if (item.index == 0){
output = '---\n' +
'title: "' + item.title + '"\n' +
'date: "' + item.date + '"\n' +
'prev: "' + data[prevIndex].id + '"\n' +
'---';
}else if (data[prevIndex] == undefined){
output = '---\n' +
'title: "' + item.title + '"\n' +
'date: "' + item.date + '"\n' +
'next: "' + data[nextIndex].id + '"\n' +
'---';
}else{
output = '---\n' +
'title: "' + item.title + '"\n' +
'date: "' + item.date + '"\n' +
'next: "' + data[nextIndex].id + '"\n' +
'prev: "' + data[prevIndex].id + '"\n' +
'---';
}
output += '\n' + item.contentData
fs.writeFile(outputFile, output, { flag: 'w' }, function (err) {
if (err) return console.log(err);
});
})
}
const data = getSortedPostsData()
// Adds an index for prev/next output
Object.values(data).forEach((data, index)=> {
data.index = index
}
);
writeNewData(data)
That's it. I read it, add it, and write it.
Battery dying on laptop. Night for now.