A 3 by 3 matrix of yellow post-it notes on a white background with the last being placed by a barely seen hand

Post List Page

This implementation happened in Gatsby 2 days.

Initial Requirements

  • When use clicks on one of the navigation links, they go to a list of posts related to that section.
  • Six posts per page seems like a good fit (can always change right?)
  • Initial version should just be a simple list entry for each post
  • Advanced version should allow the user to switch to tile view to see a more picturesque view

Collection Specific

  • Site section will include implementation date
  • CoverImage for this page is collection based
    • /blog - ?.jpg
    • /site - ?.jpg
    • /project -?.jpg (for now, the Moog picture)

Site Picture - Construction Site

1<span
2 >Photo by
3 <a
4 href="<https://unsplash.com/@tuannguyenminh?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText>"
5 >Tuân Nguyễn Minh</a
6 >
7 on
8 <a
9 href="<https://unsplash.com/s/photos/site?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText>"
10 >Unsplash</a
11 ></span
12>

Or in Markdown as it eventually exists...

1Photo by [Tuân Nguyễn Minh (@tuannguyenminh)](https://unsplash.com/@tuannguyenminh?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)
2on [Unsplash](https://unsplash.com/s/photos/site?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)

Basic Look

Stealing the basic look from narative's novela theme. It won't be this exactly though. I think I'd like a featured flag somewhere.

  • CoverImage, title, excerpt, publish date, time to read

Implementation

Using code from Skillthrive tutorial to make paginated pages. But, it has to be for each section, so there is that! Ooo it's difficult-ish. Suddenly, I'm supposed to really know JavaScript 😂

Used repl.it to work through some things. See my little GatsbySectionPages to see what I came up with.

coverImage Query
1export const coverImage = graphql`
2 query CoverImageQuery($coverImage: String!) {
3 imageSharp(fluid: { originalName: { eq: $coverImage } }) {
4 fluid {
5 ...GatsbyImageSharpFluid
6 }
7 }
8 }
9`

I knew I wanted to have three pages, one for each type of content: blog, site, & project. I also knew I wanted to have a limited amount of posts per page so I'd need pagination.

I had seen how to do pagination in the Skillthrive tutorial, but, I wanted pages for each type of post. I could see how to do this in other languages I've used but not JavaScript.

I want to go through the edges array returned from GraphQL. It is standard tutorial level Gatsby except I had added the collection to fields.

1query {
2 allMdx(sort: { fields: frontmatter___date, order: DESC }) {
3 edges {
4 node {
5 id
6 frontmatter {
7 slug
8 }
9 fields {
10 collection
11 }
12 }
13 }
14 }
15}

I landed on some articles and such about arrays, but never really got what I needed. Still, after getting bits and pieces from many articles, I was able to figure it out!

Found this: https://www.w3resource.com/javascript-exercises/fundamental/javascript-fundamental-exercise-70.php

This got me to the base function that does the work, collectionCount.

gatsby-node.js snippet
1// Create paginated pages for posts
2const postsPerPage = 6
3const edges = data.allMdx.edges
4const collectionCount = (arr, val) => arr.reduce((a, edge) => (edge.node.fields.collection === val ? a + 1 : a), 0)
5
6let groups = []
7
8groups.push({ groupName: 'blog', count: collectionCount(edges, 'blog') })
9groups.push({ groupName: 'project', count: collectionCount(edges, 'project') })
10groups.push({ groupName: 'site', count: collectionCount(edges, 'site') })
11
12groups.forEach(({ groupName, count }) => {
13 const numPages = Math.ceil(count / postsPerPage)
14 Array.from({ length: numPages }).forEach((_, i) => {
15 actions.createPage({
16 path: i === 0 ? `/${groupName}` : `/${groupName}/${i + 1}`,
17 component: require.resolve('./src/templates/post-list.js'),
18 context: {
19 limit: postsPerPage,
20 skip: i * postsPerPage,
21 numPages,
22 currentPage: i + 1,
23 collection: groupName,
24 coverImage: `${groupName}-cover.jpg`,
25 },
26 })
27 })
28})

I should explain it to myself!

Hey self...

  • Pass in an array (arr) and a value (val) which is the collection name (and probably should be renamed
  • Run reduce on the array and pass in the accumulator (a) and the current value (edge)
  • Function looks at the collection to see if it matches the value passed in and if so, adds one to the accumulator
  • Zero is the initial value so if the passed value isn't matched, it will return zero as it should

The next bit of code looks like procedural code and could probably be expressed better. But, it is working. The groups array is filled with objects that has the count of entries for each section.

The rest is plugging in the groupName and count into the Skillthrive code for creating pages based on number of posts and number of posts per page.

Post List Template

Using some GraphQL from Skillthrive tutorial modified to filter by the collection passed in the pageContext from createPage(), I've got all the data needed to display a list of posts. As there are less than 6 posts currently, there is no pagination required so it has not been implemented yet. Sometimes I'm like that!

I added some basic Tailwind styling so it isn't just text smashed together. Then, added a bit more work (late at night…should have been sleeping!) to get the cover image to show. I figured it would be easy.

I ended up with the exact same image on two different posts which was expected. However, one post had more text in the excerpt and the base flexbox implementation started shrinking one of the pictures. It looked funny! I added flex-none on the image. After all, it was correctly sized enough for now.

And sometimes, I'm not like that. I also added some default cover pictures for each section and have not used them yet.

Retrospective

  • Each section will get its own Mdx file in src/sections/ directory.
  • Frontmatter will be simply title and coverImage. I don't think I should use excerpt because there is not one.
  • This may need to be put into a new component.

Tasks

⬜ coverImage should come from Mdx
⬜ Page content should come from Mdx

2022 Retrospective

  • I did not make the list of posts be a simple list / switch to tile. I just went with tile.
  • I did not choose to put the implementation date in site. Or, more likely, I forgot until right now. Yes, I know it is years later!
  • src/sections turned out to be better as content/collections
Attributions

Photo by Kelly Sikkema (@kellysikkema) on Unsplash

Built with Gatsby from 2020 thru 2024 (and beyond?!)