Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds pagination to tags & categories #35

Merged
merged 4 commits into from
Dec 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ exclude_paths:
- static/**/*
- content/**/*
- cypress/**/*
- gatsby-config.js
- gatsby-node.js
218 changes: 138 additions & 80 deletions gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,27 @@ const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
const { paginate } = require('gatsby-awesome-pagination');

exports.createPages = ({ graphql, actions }) => {
exports.createPages = async function ({ actions, graphql }) {
const { createPage } = actions;
const itemsPerPage = 5;

/**
* Homepage
* */
const indexTemplate = path.resolve('./src/templates/index.js');
createPage({
path: '/',
component: indexTemplate,
});
return graphql(

/**
* Blog
* */
const blogPosts = await graphql(
`
{
{
allMdx(
sort: { fields: [frontmatter___date], order: DESC }
sort: { fields: [frontmatter___date], order: DESC }
limit: 1000
) {
edges {
Expand All @@ -29,104 +37,154 @@ exports.createPages = ({ graphql, actions }) => {
}
}
}
`,
)
.then((result) => {
if (result.errors) {
throw result.errors;
}

// Create blog posts pages.
const posts = result.data.allMdx.edges;
`,
);

const postTemplate = path.resolve('./src/templates/post.js');
const blogTemplate = path.resolve('./src/templates/blog.js');
const posts = blogPosts.data.allMdx.edges;
const postTemplate = path.resolve('./src/templates/post.js');
const blogPostPromises = posts.map(async (edge, index) => {
const previous = index === posts.length - 1 ? null : posts[index
+ 1].node;
const next = index === 0 ? null : posts[index - 1].node;
createPage({
path: `/blog/${edge.node.frontmatter.slug}/`,
component: postTemplate,
context: {
slug: edge.node.frontmatter.slug,
previous,
next,
},
});
});

posts.forEach((post, index) => {
const previous = index === posts.length - 1 ? null : posts[index + 1].node;
const next = index === 0 ? null : posts[index - 1].node;
await Promise.all(blogPostPromises);

createPage({
path: `/blog/${post.node.frontmatter.slug}/`,
component: postTemplate,
context: {
slug: post.node.frontmatter.slug,
previous,
next,
},
});
});
// Create a paginated blog, e.g., /, /page/2, /page/3
const blogTemplate = path.resolve('./src/templates/blog.js');
paginate({
createPage,
items: posts,
itemsPerPage,
pathPrefix: ({ pageNumber }) => (pageNumber === 0
? '/blog'
: '/blog/page'),
component: blogTemplate,
context: {
paginate_link: '/blog',
},
});

// Create a paginated blog, e.g., /, /page/2, /page/3
paginate({
createPage,
items: posts,
itemsPerPage: 10,
pathPrefix: ({ pageNumber }) => (pageNumber === 0 ? '/blog' : '/blog/page'),
component: blogTemplate,
});
})
.then(() => graphql(
`
/**
* Tag pages + pagination
* */
const distinctTags = await graphql(
`
{
allMdx {
distinct(field: frontmatter___tags)
}
}
`,
))
.then((result) => {
if (result.errors) {
throw result.errors;
);
const tagList = distinctTags.data.allMdx.distinct;
const tagsTemplate = path.resolve('./src/templates/tag.js');
const tagPromises = tagList.map(async (tag) => {
await graphql(
`
{
allMdx(filter: {frontmatter: {tags: {in: "${tag}"}}}) {
edges {
node {
id
frontmatter {
title
slug
}
body
}
}
}
}
`,
).then((tagPosts) => {
if (tagPosts.errors) {
throw tagPosts.errors;
}
const tagLower = tag.toLowerCase();
paginate({
createPage,
items: tagPosts.data.allMdx.edges,
itemsPerPage,
pathPrefix: ({ pageNumber }) => (pageNumber === 0
? `/blog/tags/${tagLower}`
: `/blog/tags/${tagLower}/page`),
component: tagsTemplate,
context: {
name: tag,
slug: tagLower,
paginate_link: `/blog/tags/${tagLower}`,
},
});
});
});

const tagsTemplate = path.resolve('./src/templates/tag.js');

// Create blog tag pages.
const tags = result.data.allMdx.distinct;
await Promise.all(tagPromises);

tags.forEach((tag) => {
// Todo Enter/Update graphQL
createPage({
path: `/blog/tags/${tag}/`,
component: tagsTemplate,
context: {
name: tag,
slug: tag.toLowerCase(),
},
});
});
})
.then(() => graphql(
`
/**
* Category pages + pagination
* */
const distinctCategories = await graphql(
`
{
allMdx {
distinct(field: frontmatter___category)
}
}
`,
))
.then((result) => {
if (result.errors) {
throw result.errors;
}

const categoriesTemplate = path.resolve('./src/templates/category.js');
);

// Create blog category pages.
const categories = result.data.allMdx.distinct;

categories.forEach((category) => {
createPage({
path: `/blog/categories/${category}/`,
component: categoriesTemplate,
context: {
name: category,
slug: category,
},
});
const categoryList = distinctCategories.data.allMdx.distinct;
const categoriesTemplate = path.resolve('./src/templates/category.js');
const categoryPromises = categoryList.map(async (category) => {
await graphql(
`
{
allMdx(filter: {frontmatter: {category: {eq: "${category}"}}}) {
edges {
node {
id
frontmatter {
title
slug
}
body
}
}
}
}
`,
).then((categoryPosts) => {
if (categoryPosts.errors) {
throw categoryPosts.errors;
}
paginate({
createPage,
items: categoryPosts.data.allMdx.edges,
itemsPerPage,
pathPrefix: ({ pageNumber }) => (pageNumber === 0
? `/blog/categories/${category}`
: `/blog/categories/${category}/page`),
component: categoriesTemplate,
context: {
name: category,
slug: category,
paginate_link: `/blog/categories/${category}`,
},
});
});
});

await Promise.all(categoryPromises);
};

exports.onCreateNode = ({ node, actions, getNode }) => {
Expand Down
9 changes: 0 additions & 9 deletions src/assets/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,6 @@ footer.footer {
font-weight: $weight-semibold;
}

.navbar {
border-top: 3px solid $primary-color;
border-bottom: 1px solid $background-grey;
}

.navbar-end {
margin-right: 0.5rem;
}

.no-html-scroll {
overflow: hidden;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import React from 'react';
import { Link } from 'gatsby';
import './pagination.scss';

const Pagination = ({ pageContext }) => {
const { previousPagePath, nextPagePath } = pageContext;
const defaultLink = pageContext.paginate_link;
const pageLink = `${defaultLink}/page`;

// A sweet helper function to create pagination object
const createPaginationObjects = (length, page, increment = 2) => Array
.from({ length }, (_, i) => ({
link: `/blog/page/${i + increment}/`,
link: `${pageLink}/${i + increment}/`,
index: i + increment,
current: page === i + increment,
}));
Expand All @@ -16,21 +19,21 @@ const Pagination = ({ pageContext }) => {
const page = pageContext.humanPageNumber;
let navItems = [
{
link: '/blog/',
link: defaultLink,
index: 1,
current: pages === 1,
current: page === 1,
},
];

if (typeof pages === 'undefined') {
if (typeof pages === 'undefined' || pages === 1) {
return '';
}

if (pages <= 5) {
navItems = [
...navItems,
...Array.from({ length: pages - 1 }, (_, i) => ({
link: `/blog/page/${i + 2}/`,
link: `${pageLink}/${i + 2}/`,
index: i + 2,
current: page === i + 2,
})),
Expand All @@ -50,7 +53,7 @@ const Pagination = ({ pageContext }) => {
index: 'starter-separator',
},
{
link: `/blog/page/${pages}/`,
link: `${pageLink}/${pages}/`,
index: pages,
current: false,
},
Expand Down Expand Up @@ -78,7 +81,7 @@ const Pagination = ({ pageContext }) => {
index: 'finisher-separator',
},
{
link: `/blog/page/${pages}/`,
link: `${pageLink}/${pages}/`,
index: pages,
current: false,
},
Expand All @@ -87,7 +90,6 @@ const Pagination = ({ pageContext }) => {
}
return (
<section>
<br />
<nav
className="pagination is-centered navbar"
role="navigation"
Expand Down
11 changes: 11 additions & 0 deletions src/components/blog/pagination/pagination.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.pagination {
margin-top: 0.5em;
}

.pagination-previous {
margin-left: 1em;
}

.pagination-next {
margin-right: 1em;
}
2 changes: 1 addition & 1 deletion src/components/navbar/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import NavbarItem from './item/navbarItem';
import NavbarBurger from './burger/navbarBurger';
import NavbarItemSocial from './itemSocial/navbarItemSocial';
import NavbarLogo from './logo/navbarLogo';
import './navbar.scss';
import Search from '../search/search';
import './navbar.scss';

export default class Navbar extends React.Component {
constructor(props) {
Expand Down
8 changes: 7 additions & 1 deletion src/components/navbar/navbar.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
@import "../../assets/styles/main";
@import "~bulma/bulma";

.navbar {
border-top: 3px solid $primary-color;
border-bottom: 1px solid $background-grey;
}

.navbar-item {
font-weight: $weight-bold;
margin-top: auto;
}

button.navbar-item.searchButton {
margin-right: 0.5em;

@include touch {
margin: 0 auto;
}
Expand Down
Loading