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

Commit 4453447

Browse files
author
Greg Rickaby
authored
Merge pull request #118 from WebDevStudios/feature/33-previews
Feature/33 previews
2 parents e624b00 + 9a16eb4 commit 4453447

21 files changed

+255
-92
lines changed

api/wordpress/_global/getPostTypeArchive.js

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,31 @@ import getMenus from '../menus/getMenus'
1414
export const archiveSeo = {
1515
career: {
1616
title: 'Careers',
17-
description: '',
18-
route: 'careers'
17+
description: ''
1918
},
2019
event: {
2120
title: 'Events',
22-
description: '',
23-
route: 'events'
21+
description: ''
2422
},
2523
portfolio: {
2624
title: 'Portfolio',
27-
description: '',
28-
route: 'portfolio'
25+
description: ''
2926
},
3027
post: {
3128
title: 'Blog',
32-
description: '',
33-
route: 'blog'
29+
description: ''
3430
},
3531
service: {
3632
title: 'Services',
37-
description: '',
38-
route: 'service'
33+
description: ''
3934
},
4035
team: {
4136
title: 'Team Members',
42-
description: '',
43-
route: 'team'
37+
description: ''
4438
},
4539
testimonial: {
4640
title: 'Testimonials',
47-
description: '',
48-
route: 'testimonial'
41+
description: ''
4942
}
5043
}
5144

@@ -126,7 +119,7 @@ export default async function getPostTypeArchive(
126119
// Retrieve default SEO data.
127120
response.defaultSeo = formatDefaultSeoData({homepageSettings, siteSeo})
128121

129-
const pluralType = postTypes[postType] ?? postType
122+
const pluralType = postTypes[postType]?.pluralName ?? postType
130123
const data = archiveData?.[pluralType] ?? null
131124

132125
// Set error props if data not found.
@@ -147,7 +140,7 @@ export default async function getPostTypeArchive(
147140
? {
148141
...homepageSettings.postsPage.seo,
149142
canonical: `${response.defaultSeo?.openGraph?.url ?? ''}/${
150-
archiveSeo?.[postType]?.route
143+
postTypes?.[postType]?.route
151144
}`
152145
}
153146
: {
@@ -156,7 +149,7 @@ export default async function getPostTypeArchive(
156149
}`,
157150
metaDesc: archiveSeo?.[postType]?.description,
158151
canonical: `${response.defaultSeo?.openGraph?.url ?? ''}/${
159-
archiveSeo?.[postType]?.route
152+
postTypes?.[postType]?.route
160153
}`,
161154
metaRobotsNofollow: 'follow',
162155
metaRobotsNoindex: 'index'

api/wordpress/_global/getPostTypeById.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import queryPostById from '../posts/queryPostById'
2-
import {initializeWpApollo} from '../connector'
2+
import {initializeWpApollo, createWpApolloClient} from '../connector'
33
import queryPageById from '../pages/queryPageById'
44
import {isHierarchicalPostType} from './postTypes'
55
import formatBlockData from '@/functions/formatBlockData'
@@ -19,9 +19,15 @@ import getMenus from '../menus/getMenus'
1919
* @param {string} postType WP post type.
2020
* @param {number | string} id Post identifier.
2121
* @param {string} idType Type of ID.
22+
* @param {string} preview Whether query is for a regular post view (null), a preview check (basic), or full post preview (full).
2223
* @return {object} Object containing Apollo client instance and post data or error object.
2324
*/
24-
export default async function getPostTypeById(postType, id, idType = 'SLUG') {
25+
export default async function getPostTypeById(
26+
postType,
27+
id,
28+
idType = 'SLUG',
29+
preview = null
30+
) {
2531
// Define single post query based on post type.
2632
const postTypeQuery = {
2733
career: queryCareerById,
@@ -44,7 +50,9 @@ export default async function getPostTypeById(postType, id, idType = 'SLUG') {
4450
const query = postTypeQuery?.[postType] ?? null
4551

4652
// Get/create Apollo instance.
47-
const apolloClient = initializeWpApollo()
53+
const apolloClient = preview
54+
? createWpApolloClient(true)
55+
: initializeWpApollo()
4856

4957
// Set up return object.
5058
const response = {
@@ -93,11 +101,11 @@ export default async function getPostTypeById(postType, id, idType = 'SLUG') {
93101
slug: id
94102
}
95103

96-
// Handle blocks.
97-
if (!post || !post?.blocksJSON) {
104+
if ('basic' === preview || !post || !post?.blocksJSON) {
98105
return post
99106
}
100107

108+
// Handle blocks.
101109
newPost.blocks = await formatBlockData(
102110
JSON.parse(newPost.blocksJSON) ?? []
103111
)

api/wordpress/_global/getPostTypeStaticPaths.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default async function getPostTypeStaticPaths(postType) {
1515
}
1616

1717
// Retrieve post type plural name.
18-
const pluralName = postTypes[postType]
18+
const pluralName = postTypes[postType].pluralName
1919

2020
// Check if post type is hierarchical.
2121
const isHierarchical = isHierarchicalPostType(postType)

api/wordpress/_global/getPostTypeStaticProps.js

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ import getFrontendPage, {frontendPageSeo} from './getFrontendPage'
88
* Retrieve static props by post type.
99
*
1010
* @author WebDevStudios
11-
* @param {string} params Post params (e.g., slug).
12-
* @param {string} postType Post Type.
13-
* @return {object} Object containing post props and revalidate setting.
11+
* @param {string} params Post params (e.g., slug).
12+
* @param {string} postType Post Type.
13+
* @param {boolean} preview Whether requesting preview of post.
14+
* @param {object} previewData Post preview data.
15+
* @return {object} Object containing post props and revalidate setting.
1416
*/
1517
export default async function getPostTypeStaticProps(
1618
params,
17-
postType
18-
// preview = false, // TODO - add preview handling.
19-
// previewData = null
19+
postType,
20+
preview = false,
21+
previewData = null
2022
) {
2123
// Set revalidate length (seconds).
2224
const revalidate = 60 * 5
@@ -28,7 +30,7 @@ export default async function getPostTypeStaticProps(
2830
}
2931
}
3032

31-
// Check for Frontend-only routes.
33+
/* -- Handle Frontend-only routes. -- */
3234
if (Object.keys(frontendPageSeo).includes(postType)) {
3335
const {apolloClient, ...routeData} = await getFrontendPage(postType)
3436

@@ -41,7 +43,7 @@ export default async function getPostTypeStaticProps(
4143
})
4244
}
4345

44-
// Check for dynamic archive display.
46+
/* -- Handle dynamic archive display. -- */
4547
if (!Object.keys(params).length) {
4648
const {apolloClient, ...archiveData} = await getPostTypeArchive(postType)
4749

@@ -56,24 +58,43 @@ export default async function getPostTypeStaticProps(
5658
})
5759
}
5860

61+
/* -- Handle individual posts. -- */
62+
5963
// Handle catch-all routes.
6064
const slug = Array.isArray(params.slug) ? params.slug.join('/') : params.slug
6165

66+
// Get post identifier (ID or slug).
67+
const postId = Number.isInteger(Number(slug)) ? Number(slug) : slug
68+
69+
// Check if preview mode is active and valid for current post (preview and post IDs or slugs match).
70+
const isCurrentPostPreview =
71+
preview &&
72+
(postId === previewData?.post?.id || postId === previewData?.post?.slug)
73+
74+
// Check if viewing a draft post.
75+
const isDraft = isCurrentPostPreview && 'draft' === previewData?.post?.status
76+
77+
// Set query variables.
78+
const id = isDraft ? previewData.post.id : slug
79+
const idType = isDraft ? 'DATABASE_ID' : 'SLUG'
80+
6281
// Retrieve post data.
6382
const {apolloClient, error, ...postData} = await getPostTypeById(
6483
postType,
65-
slug
84+
id,
85+
idType,
86+
isCurrentPostPreview ? 'full' : null
6687
)
6788

6889
const props = {
6990
...postData,
7091
...sharedProps,
71-
error
92+
error,
93+
preview: isCurrentPostPreview
7294
}
7395

74-
// Custom handling for homepage.
96+
// Fallback to empty props if homepage not set in WP.
7597
if ('/' === slug && error) {
76-
// Fallback to empty props if homepage not set in WP.
7798
props.post = null
7899
props.error = false
79100
}

api/wordpress/_global/postTypes.js

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,45 @@
11
// Define valid WP post types (singular and plural GraphQL names).
22
export const postTypes = {
3-
career: 'careers',
4-
comment: 'comments',
5-
event: 'events',
6-
mediaItem: 'mediaItems',
7-
page: 'pages',
8-
portfolio: 'portfolios',
9-
post: 'posts',
10-
service: 'services',
11-
team: 'teams',
12-
testimonial: 'testimonials'
3+
career: {
4+
pluralName: 'careers',
5+
route: 'careers'
6+
},
7+
comment: {
8+
pluralName: 'comments',
9+
route: null
10+
},
11+
event: {
12+
pluralName: 'events',
13+
route: 'events'
14+
},
15+
mediaItem: {
16+
pluralName: 'mediaItems',
17+
route: null
18+
},
19+
page: {
20+
pluralName: 'pages',
21+
route: ''
22+
},
23+
portfolio: {
24+
pluralName: 'portfolios',
25+
route: 'portfolio'
26+
},
27+
post: {
28+
pluralName: 'posts',
29+
route: 'blog'
30+
},
31+
service: {
32+
pluralName: 'services',
33+
route: 'service'
34+
},
35+
team: {
36+
pluralName: 'teams',
37+
route: 'team'
38+
},
39+
testimonial: {
40+
pluralName: 'testimonials',
41+
route: 'testimonial'
42+
}
1343
}
1444

1545
// Define hierarchical post types.

api/wordpress/_global/queryDefaultPageData.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import defaultPageData from '../_partials/defaultPageData'
33

44
// Query: retrieve default SEO and other page data.
55
const queryDefaultPageData = gql`
6-
query GET_DEFAULT_SEO {
6+
query GET_DEFAULT_PAGE_DATA {
77
${defaultPageData}
88
}
99
`

api/wordpress/_partials/globalPostFields.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ const globalPostFields = `
55
slug
66
uri
77
title
8+
status
89
`
910
export default globalPostFields

api/wordpress/connector.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ import {initializeApollo} from '../apolloConfig'
44

55
// Define env vars.
66
export const wpApiUrlBase = getEnvVar('WORDPRESS_API_URL')
7+
export const wpPreviewSecret = process.env.WORDPRESS_PREVIEW_SECRET
8+
const wpAppUser = process.env.WORDPRESS_APPLICATION_USERNAME
9+
const wpAppPass = process.env.WORDPRESS_APPLICATION_PASSWORD
10+
11+
// Set WP application password auth header.
12+
const wpAuthorization = Buffer.from(`${wpAppUser}:${wpAppPass}`).toString(
13+
'base64'
14+
)
715

816
// Define Frontend WP API data endpoint base.
917
const wpDataEndpointBase = '/wp'
@@ -21,14 +29,18 @@ let wpApolloClient
2129
* @see https://www.apollographql.com/docs/react/api/core/ApolloClient/
2230
*
2331
* @author WebDevStudios
24-
* @return {object} Apollo client instance.
32+
* @param {boolean} auth Whether to include authentication via WP application password.
33+
* @return {object} Apollo client instance.
2534
*/
26-
export function createWpApolloClient() {
35+
export function createWpApolloClient(auth = false) {
2736
return new ApolloClient({
2837
ssrMode: false,
2938
link: new HttpLink({
3039
uri: `${wpApiUrlBase}graphql`,
31-
credentials: ''
40+
credentials: '',
41+
headers: {
42+
authorization: auth ? `Basic ${wpAuthorization}` : ''
43+
}
3244
}),
3345
cache: new InMemoryCache()
3446
})

functions/getPagePropTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export const postPropTypes = {
4949
excerpt: PropTypes.string,
5050
featuredImage: PropTypes.object,
5151
...seoPropTypes,
52-
slug: PropTypes.string,
52+
slug: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
5353
title: PropTypes.string,
5454
uri: PropTypes.string
5555
})

pages/[...slug].js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ export async function getStaticPaths() {
5454
* Get post static props.
5555
*
5656
* @author WebDevStudios
57-
* @param {object} context Context for current post.
58-
* @param {object} context.params Route parameters for current post.
59-
* @return {object} Post props.
57+
* @param {object} context Context for current post.
58+
* @param {object} context.params Route parameters for current post.
59+
* @param {boolean} context.preview Whether requesting preview of post.
60+
* @param {object} context.previewData Post preview data.
61+
* @return {object} Post props.
6062
*/
61-
export async function getStaticProps({params}) {
62-
return getPostTypeStaticProps(params, postType)
63+
export async function getStaticProps({params, preview, previewData}) {
64+
return getPostTypeStaticProps(params, postType, preview, previewData)
6365
}
6466

6567
Page.propTypes = {

0 commit comments

Comments
 (0)