Skip to content
This repository was archived by the owner on Feb 27, 2024. It is now read-only.

Commit f2049a6

Browse files
authored
Merge pull request #42 from WebDevStudios/feature/33-basic-post-page-queries
Feature/33 basic post page queries
2 parents 6fe05d0 + 849eb1e commit f2049a6

File tree

22 files changed

+429
-68
lines changed

22 files changed

+429
-68
lines changed
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import queryPostById from '../posts/queryPostById'
2+
import {initializeApollo} from '../connector'
3+
import queryPageById from '../pages/queryPageById'
4+
import {isHierarchicalPostType} from './postTypes'
5+
6+
/**
7+
* Retrieve single post by specified identifier.
8+
*
9+
* @author WebDevStudios
10+
* @param {string} postType WP post type.
11+
* @param {Number|string} id Post identifier.
12+
* @param {string} idType Type of ID.
13+
* @return {Object} Post data or error object.
14+
*/
15+
export default async function getPostTypeById(postType, id, idType = 'SLUG') {
16+
// Define single post query based on post type.
17+
const postTypeQuery = {
18+
page: queryPageById,
19+
post: queryPostById
20+
}
21+
22+
// Check if post type is hierarchical.
23+
const isHierarchical = isHierarchicalPostType(postType)
24+
25+
// Fix default ID type for hierarchical posts.
26+
idType = !isHierarchical || 'SLUG' !== idType ? idType : 'URI'
27+
28+
// Retrieve post type query.
29+
const query = postTypeQuery?.[postType] ?? null
30+
31+
// If no query is set for given post type, return error message.
32+
if (!query) {
33+
return {
34+
isError: true,
35+
message: `Post type \`${postType}\` is not supported.`
36+
}
37+
}
38+
39+
// Get/create Apollo instance.
40+
const apolloClient = initializeApollo()
41+
42+
// Execute query.
43+
const post = await apolloClient
44+
.query({query, variables: {id, idType}})
45+
.then((post) => post?.data?.[postType] ?? null)
46+
.catch((error) => {
47+
return {
48+
isError: true,
49+
message: error.message
50+
}
51+
})
52+
53+
if (!post) {
54+
return {
55+
isError: true,
56+
message: `An error occurred while trying to retrieve data for ${postType} "${id}."`
57+
}
58+
}
59+
60+
return post
61+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import {gql} from '@apollo/client'
2+
import {isValidPostType, postTypes, isHierarchicalPostType} from './postTypes'
3+
import {initializeApollo} from '../connector'
4+
5+
/**
6+
* Retrieve static paths by post type.
7+
*
8+
* @author WebDevStudios
9+
* @param {string} postType WP post type.
10+
* @return {Object} Post type paths.
11+
*/
12+
export default async function getPostTypeStaticPaths(postType) {
13+
if (!postType || !isValidPostType(postType)) {
14+
return null
15+
}
16+
17+
// Retrieve post type plural name.
18+
const pluralName = postTypes[postType]
19+
20+
// Check if post type is hierarchical.
21+
const isHierarchical = isHierarchicalPostType(postType)
22+
23+
// Determine path field based on hierarchy.
24+
const pathField = isHierarchical ? 'uri' : 'slug'
25+
26+
// Construct query based on post type.
27+
const query = gql`
28+
query GET_SLUGS {
29+
${pluralName}(first: 10000) {
30+
nodes {
31+
${pathField}
32+
}
33+
}
34+
}
35+
`
36+
37+
// Get/create Apollo instance.
38+
const apolloClient = initializeApollo()
39+
40+
// Execute query.
41+
const posts = await apolloClient.query({query})
42+
43+
// Process paths.
44+
const paths = !posts?.data?.[pluralName]?.nodes
45+
? []
46+
: posts.data[pluralName].nodes.map((post) => {
47+
// Use path field as-is for non-hierarchical post types.
48+
// Trim leading and trailing slashes then split into array on inner slashes for hierarchical post types.
49+
const slug = !isHierarchical
50+
? post[pathField]
51+
: post[pathField].replace(/^\/|\/$/g, '').split('/')
52+
53+
return {
54+
params: {
55+
slug
56+
}
57+
}
58+
})
59+
60+
return {
61+
paths,
62+
fallback: false
63+
}
64+
}

api/wordpress/_global/postTypes.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Define valid WP post types (singular and plural GraphQL names).
2+
export const postTypes = {
3+
career: 'careers',
4+
comment: 'comments',
5+
event: 'events',
6+
mediaItem: 'mediaItems',
7+
page: 'pages',
8+
porfolio: 'portfolios',
9+
post: 'posts',
10+
service: 'services',
11+
team: 'teams',
12+
testimonial: 'testimonials'
13+
}
14+
15+
// Define hierarchical post types.
16+
export const hierarchicalPostTypes = ['page']
17+
18+
/**
19+
* Check if post type is valid.
20+
*
21+
* @author WebDevStudios
22+
* @param {string} postType WP post type.
23+
* @return {bool} Whether provided post type is valid.
24+
*/
25+
export function isValidPostType(postType) {
26+
return Object.keys(postTypes).includes(postType)
27+
}
28+
29+
/**
30+
* Check if post type is hierarchical.
31+
*
32+
* @author WebDevStudios
33+
* @param {string} postType WP post type.
34+
* @return {bool} Whether provided post type is hierarchical.
35+
*/
36+
export function isHierarchicalPostType(postType) {
37+
return hierarchicalPostTypes.includes(postType)
38+
}

api/wordpress/connector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {useMemo} from 'react'
22
import {ApolloClient, HttpLink, InMemoryCache} from '@apollo/client'
33
import merge from 'deepmerge'
44
import isEqual from 'lodash/isEqual'
5-
import {getEnvVar} from '@/lib/functions'
5+
import getEnvVar from '@/functions/getEnvVar'
66

77
// Define env vars.
88
export const wpApiUrlBase = getEnvVar('WORDPRESS_API_URL')

api/wordpress/pages/queryPageById.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const {gql} = require('@apollo/client')
2+
3+
// Query: retrieve page by specified identifier.
4+
const queryPageById = gql`
5+
query GET_PAGE_BY_SLUG($id: ID!, $idType: PageIdType = URI) {
6+
page(id: $id, idType: $idType) {
7+
blocksJSON
8+
databaseId
9+
date
10+
slug
11+
title
12+
excerpt
13+
seo {
14+
canonical
15+
title
16+
metaDesc
17+
metaRobotsNofollow
18+
metaRobotsNoindex
19+
opengraphImage {
20+
sourceUrl
21+
}
22+
}
23+
author {
24+
node {
25+
slug
26+
nickname
27+
}
28+
}
29+
featuredImage {
30+
node {
31+
altText
32+
sourceUrl(size: LARGE)
33+
}
34+
}
35+
}
36+
}
37+
`
38+
39+
export default queryPageById

api/wordpress/posts/queryPostById.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const {gql} = require('@apollo/client')
2+
3+
// Query: retrieve post by specified identifier.
4+
const queryPostById = gql`
5+
query GET_POST_BY_SLUG($id: ID!, $idType: PostIdType = SLUG) {
6+
post(id: $id, idType: $idType) {
7+
blocksJSON
8+
databaseId
9+
date
10+
slug
11+
title
12+
excerpt
13+
seo {
14+
canonical
15+
title
16+
metaDesc
17+
metaRobotsNofollow
18+
metaRobotsNoindex
19+
opengraphImage {
20+
sourceUrl
21+
}
22+
}
23+
tags {
24+
edges {
25+
node {
26+
name
27+
slug
28+
}
29+
}
30+
}
31+
author {
32+
node {
33+
slug
34+
nickname
35+
}
36+
}
37+
categories {
38+
edges {
39+
node {
40+
slug
41+
name
42+
}
43+
}
44+
}
45+
featuredImage {
46+
node {
47+
altText
48+
sourceUrl(size: LARGE)
49+
}
50+
}
51+
}
52+
}
53+
`
54+
55+
export default queryPostById

components/common/Layout.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import PropTypes from 'prop-types'
22
import Meta from './Meta'
33
import Header from '../organisms/Header'
44
import Footer from '../organisms/Footer'
5-
import config from '@/lib/config'
5+
import config from '@/functions/config'
66

77
export default function Layout({children, ...props}) {
88
return (

components/common/Meta.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import config from '@/lib/config'
1+
import config from '@/functions/config'
22
import Head from 'next/head'
33
import PropTypes from 'prop-types'
44

components/organisms/Footer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import Link from 'next/link'
2-
import config from '@/lib/config'
2+
import config from '@/functions/config'
33

44
export default function Footer() {
55
return (

components/organisms/Navigation.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {useState} from 'react'
22
import Link from 'next/link'
3-
import config from '@/lib/config'
3+
import config from '@/functions/config'
44
import Hamburger from 'hamburger-react'
55

66
function Links() {

0 commit comments

Comments
 (0)