Skip to content

Instantly share code, notes, and snippets.

@flying3615
Created August 7, 2019 22:16
Show Gist options
  • Save flying3615/d8cca7221b7f4051f7a00cd911637234 to your computer and use it in GitHub Desktop.
Save flying3615/d8cca7221b7f4051f7a00cd911637234 to your computer and use it in GitHub Desktop.
import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'
import styled from '@emotion/styled'
import { Layout, Listing, Wrapper, Title, SEO, Header } from '../components'
import website from '../../config/website'
const Hero = styled.header`
padding-top: 1rem;
padding-bottom: 4rem;
h1 {
color: ${props => props.theme.colors.bg};
}
`
const Headline = styled.p`
font-family: 'Source Sans Pro', -apple-system, 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica', 'Arial',
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
color: ${props => props.theme.colors.greyBlue};
font-size: 1.25rem;
a {
font-style: normal;
font-weight: normal;
}
`
const CatWrapper = Wrapper.withComponent('main')
const Category = ({
pageContext: { category },
data: {
posts: { nodes, totalCount },
},
location,
}) => (
<Layout>
<SEO title={`Category: ${category} | ${website.titleAlt}`} pathname={location.pathname} />
<Hero>
<Wrapper>
<Header invert />
<Headline>Category</Headline>
<h1>{category}</h1>
</Wrapper>
</Hero>
<CatWrapper id={website.skipNavId}>
<Title style={{ marginTop: '4rem' }}>
{totalCount} {totalCount === 1 ? 'Post' : 'Posts'} {totalCount === 1 ? 'was' : 'were'} tagged with "{category}"
</Title>
<Listing posts={nodes} />
</CatWrapper>
</Layout>
)
export default Category
Category.propTypes = {
pageContext: PropTypes.shape({
category: PropTypes.string.isRequired,
}).isRequired,
data: PropTypes.shape({
posts: PropTypes.shape({
nodes: PropTypes.array.isRequired,
totalCount: PropTypes.number.isRequired,
}).isRequired,
}).isRequired,
location: PropTypes.object.isRequired,
}
export const pageQuery = graphql`
query CategoryPage($category: String!) {
posts: allPrismicPost(
sort: { fields: [data___date], order: DESC }
filter: {
data: {
categories: { elemMatch: { category: { document: { elemMatch: { data: { name: { eq: $category } } } } } } }
}
}
) {
totalCount
nodes {
uid
data {
title {
text
}
date(formatString: "DD.MM.YYYY")
categories {
category {
document {
data {
name
}
}
}
}
}
}
}
}
`
const _ = require('lodash')
// graphql function doesn't throw an error so we have to check to check for the result.errors to throw manually
const wrapper = promise =>
promise.then(result => {
if (result.errors) {
throw result.errors
}
return result
})
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const postTemplate = require.resolve('./src/templates/post.jsx')
const categoryTemplate = require.resolve('./src/templates/category.jsx')
const result = await wrapper(
graphql(`
{
allPrismicPost {
edges {
node {
id
uid
data {
categories {
category {
document {
data {
name
}
}
}
}
}
}
}
}
}
`)
)
const categorySet = new Set()
const postsList = result.data.allPrismicPost.edges
// Double check that the post has a category assigned
postsList.forEach(edge => {
if (edge.node.data.categories[0].category) {
edge.node.data.categories.forEach(cat => {
categorySet.add(cat.category.document[0].data.name)
})
}
// The uid you assigned in Prismic is the slug!
createPage({
path: `/${edge.node.uid}`,
component: postTemplate,
context: {
// Pass the unique ID (uid) through context so the template can filter by it
uid: edge.node.uid,
},
})
})
const categoryList = Array.from(categorySet)
categoryList.forEach(category => {
createPage({
path: `/categories/${_.kebabCase(category)}`,
component: categoryTemplate,
context: {
category,
},
})
})
}
import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'
import styled from '@emotion/styled'
import { Disqus } from 'gatsby-plugin-disqus'
import { Layout, Listing, Wrapper, SliceZone, Title, SEO, Header } from '../components'
import Categories from '../components/Listing/Categories'
import website from '../../config/website'
const Hero = styled.header`
padding-top: 1rem;
padding-bottom: 4rem;
`
const Headline = styled.p`
font-family: 'Source Sans Pro', -apple-system, 'BlinkMacSystemFont', 'Segoe UI', 'Roboto', 'Helvetica', 'Arial',
sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
color: ${props => props.theme.colors.grey};
font-size: 1.25rem;
a {
font-style: normal;
font-weight: normal;
}
`
const PostWrapper = Wrapper.withComponent('main')
const Post = ({ data: { prismicPost, posts }, location }) => {
const { data } = prismicPost
let categories = false
if (data.categories[0].category) {
categories = data.categories.map(c => c.category.document[0].data.name)
}
const disqusConfig = {
identifier: data.title.text,
title: data.title.text,
}
return (
<Layout customSEO>
<SEO
title={`${data.title.text} | ${website.titleAlt}`}
pathname={location.pathname}
desc={data.description}
node={prismicPost}
article
/>
<Hero>
<Wrapper>
<Headline>
{data.date} — {categories && <Categories categories={categories} />}
</Headline>
<h1>{data.title.text}</h1>
</Wrapper>
</Hero>
<PostWrapper id={website.skipNavId}>
<SliceZone allSlices={data.body} />
<Title style={{ marginTop: '4rem' }}>Recent posts</Title>
<Listing posts={posts.nodes} />
<Disqus config={disqusConfig} />
</PostWrapper>
</Layout>
)
}
export default Post
Post.propTypes = {
data: PropTypes.shape({
prismicPost: PropTypes.object.isRequired,
posts: PropTypes.shape({
nodes: PropTypes.array.isRequired,
}),
}).isRequired,
location: PropTypes.object.isRequired,
}
// The typenames come from the slice names
// If this doesn't work for you query for __typename in body {} and GraphiQL will show them to you
export const pageQuery = graphql`
query PostBySlug($uid: String!) {
prismicPost(uid: { eq: $uid }) {
uid
first_publication_date
last_publication_date
data {
title {
text
}
description
date(formatString: "DD.MM.YYYY")
categories {
category {
document {
data {
name
}
}
}
}
body {
... on PrismicPostBodyText {
slice_type
id
primary {
text {
html
}
}
}
... on PrismicPostBodyCodeBlock {
slice_type
id
primary {
code_block {
html
}
}
}
... on PrismicPostBodyQuote {
slice_type
id
primary {
quote {
html
text
}
}
}
... on PrismicPostBodyImage {
slice_type
id
primary {
image {
localFile {
childImageSharp {
fluid(maxWidth: 1200, quality: 90) {
...GatsbyImageSharpFluid_withWebp
}
}
}
}
}
}
}
}
}
posts: allPrismicPost(limit: 2, sort: { fields: [data___date], order: DESC }, filter: { uid: { ne: $uid } }) {
nodes {
uid
data {
title {
text
}
date(formatString: "DD.MM.YYYY")
categories {
category {
document {
data {
name
}
}
}
}
}
}
}
}
`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment