Skip to content

Commit

Permalink
feat(gatsby-source-wordpress): enable image-cdn (#34832)
Browse files Browse the repository at this point in the history
Co-authored-by: Matt Ehlinger <ehlinger.matt@gmail.com>
Co-authored-by: veryspry <ehlinger.matt@gmail.com>
Co-authored-by: Tyler Barnes <tylerdbarnes@gmail.com>
  • Loading branch information
3 people committed Mar 1, 2022
1 parent 46fe418 commit fe29c01
Show file tree
Hide file tree
Showing 18 changed files with 388 additions and 145 deletions.
Expand Up @@ -3915,6 +3915,13 @@ Array [
"parent",
"children",
"internal",
"filename",
"filesize",
"width",
"height",
"publicUrl",
"resize",
"gatsbyImageData",
],
"name": "WpMediaItem",
},
Expand Down
9 changes: 8 additions & 1 deletion integration-tests/gatsby-source-wordpress/__tests__/index.js
Expand Up @@ -60,6 +60,10 @@ describe(`[gatsby-source-wordpress] Run tests on develop build`, () => {
let gatsbyDevelopProcess

beforeAll(async () => {
if (process.env.SKIP_BEFORE_ALL) {
return
}

if (!isWarmCache) {
await gatsbyCleanBeforeAll()
}
Expand Down Expand Up @@ -105,7 +109,10 @@ describe(`[gatsby-source-wordpress] Run tests on develop build`, () => {
require(`../test-fns/index`)

afterAll(done => {
gatsbyDevelopProcess.kill()
if (gatsbyDevelopProcess) {
gatsbyDevelopProcess.kill()
}

done()
})
})
Expand Up @@ -2,6 +2,7 @@ version: "3.2"

services:
db:
platform: linux/x86_64
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: gtsb-wp-dckr
Expand Down
Expand Up @@ -531,4 +531,44 @@ describe(`data resolution`, () => {
expect(wpMediaItem).toBeNull()
}
})

it(`Resolves Gatsby Image CDN data`, async () => {
const {
data: { allWpPost },
} = await fetchGraphql({
url,
query: /* GraphQL */ `
query {
allWpPost {
nodes {
featuredImage {
node {
mediaItemUrl
resize(width: 100, height: 100, quality: 100) {
width
height
src
}
}
}
}
}
}
`,
})

allWpPost.nodes.forEach(node => {
if (!node.featuredImage?.node) {
return
}

const { resize } = node.featuredImage.node
const [, , , sourceUrl64, _args64, filename] = resize.src.split(`/`)

const sourceUrl = Buffer.from(sourceUrl64, `base64`).toString(`ascii`)

expect(node.featuredImage.node.mediaItemUrl).toEqual(sourceUrl)
expect(node.featuredImage.node.mediaItemUrl).toContain(filename)
})
})
})
77 changes: 77 additions & 0 deletions packages/gatsby-source-wordpress/__tests__/process-node.fixture.js
@@ -0,0 +1,77 @@
export const referencedMediaItems = [
{
"id": `cG9zdDoxMTU=`,
"mediaDetails": {
"file": `2022/02/sasha-set-GURzQwO8Li0-unsplash-scaled.jpg`,
"height": 1920,
"sizes": [
{
"file": `sasha-set-GURzQwO8Li0-unsplash-300x225.jpg`,
"fileSize": 18876,
"height": `225`,
"mimeType": `image/jpeg`,
"name": `medium`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-300x225.jpg`,
"width": `300`
},
{
"file": `sasha-set-GURzQwO8Li0-unsplash-1024x768.jpg`,
"fileSize": 214590,
"height": `768`,
"mimeType": `image/jpeg`,
"name": `large`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1024x768.jpg`,
"width": `1024`
},
{
"file": `sasha-set-GURzQwO8Li0-unsplash-150x150.jpg`,
"fileSize": 7088,
"height": `150`,
"mimeType": `image/jpeg`,
"name": `thumbnail`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-150x150.jpg`,
"width": `150`
},
{
"file": `sasha-set-GURzQwO8Li0-unsplash-768x576.jpg`,
"fileSize": 118086,
"height": `576`,
"mimeType": `image/jpeg`,
"name": `medium_large`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-768x576.jpg`,
"width": `768`
},
{
"file": `sasha-set-GURzQwO8Li0-unsplash-1536x1152.jpg`,
"fileSize": 490613,
"height": `1152`,
"mimeType": `image/jpeg`,
"name": `1536x1536`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1536x1152.jpg`,
"width": `1536`
},
{
"file": `sasha-set-GURzQwO8Li0-unsplash-2048x1536.jpg`,
"fileSize": 858627,
"height": `1536`,
"mimeType": `image/jpeg`,
"name": `2048x2048`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-2048x1536.jpg`,
"width": `2048`
}
],
"width": 2560
},
"mediaItemUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-scaled.jpg`,
"mediaType": `image`,
"mimeType": `image/jpeg`,
"sourceUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-scaled.jpg`,
"srcSet": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-300x225.jpg 300w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1024x768.jpg 1024w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-768x576.jpg 768w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1536x1152.jpg 1536w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-2048x1536.jpg 2048w`,
"width": 2560,
"height": 1920,
"placeholderUrl": `http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-300x225.jpg`,
"internal": {
"contentDigest": `5fa24d43c7fc603f9016933ad6bb3ee4`,
}
}
]
71 changes: 69 additions & 2 deletions packages/gatsby-source-wordpress/__tests__/process-node.test.js
@@ -1,8 +1,10 @@
import execall from "execall"

import { replaceNodeHtmlImages } from "../dist/steps/source-nodes/create-nodes/process-node"

import {
getImgSrcRemoteFileMatchesFromNodeString,
getImgTagMatchesWithUrl,
getImgTagMatches,
getWpLinkRegex,
searchAndReplaceNodeStrings,
} from "../dist/steps/source-nodes/create-nodes/process-node"
Expand All @@ -20,7 +22,7 @@ test(`HTML image transformation regex matches images`, async () => {

expect(matches.length).toBe(3)

const imgTagMatches = getImgTagMatchesWithUrl({
const imgTagMatches = getImgTagMatches({
nodeString,
wpUrl: `https://${wpUrl}`,
})
Expand Down Expand Up @@ -69,3 +71,68 @@ test(`Search and replace node strings using regex matches`, async () => {
We need to test some <a href=\\"https://new-site.com/hi\\" />link</a> as well!`)
})

jest.mock(`../dist/steps/source-nodes/fetch-nodes/fetch-referenced-media-items.js`, () => {
return {
__esModule: true,
...jest.requireActual(`../dist/steps/source-nodes/fetch-nodes/fetch-referenced-media-items.js`),
default: jest.fn(() => require(`./process-node.fixture`).referencedMediaItems)
}
})


test(`Gatsby Image service works in html fields via replaceNodeHtmlImages`, async () => {
const node = {
content: `\n<p>Welcome to WordPress. This is your first post. Edit or deleteit, then start writing!</p>\n\n\n\n<p></p>\n\n\n\n<figureclass="wp-block-image size-large"><img loading="lazy" width="1024" height="768" src="http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1024x768.jpg" alt=""class="wp-image-115" srcset="http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1024x768.jpg 1024w,http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-300x225.jpg 300w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-768x576.jpg 768w,http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-1536x1152.jpg 1536w, http://wpgatsby.local/wp-content/uploads/2022/02/sasha-set-GURzQwO8Li0-unsplash-2048x1536.jpg 2048w"sizes="(max-width: 1024px) 100vw, 1024px" /></figure>\n`,
id: `cG9zdDox`,
modifiedGmt: `2022-02-18T23:18:00`,
__typename: `Post`
}

const gatsbyImageUrl = `/_gatsby/image`

const nodeString = JSON.stringify(node)

const updatedNodeString = await replaceNodeHtmlImages({
nodeString,
node,
helpers: {
reporter: console
},
wpUrl: `http://wpgatsby.local/`,
pluginOptions: {
html: {
useGatsbyImage: true
}
}
})

expect(updatedNodeString).toInclude(gatsbyImageUrl)
expect(updatedNodeString).not.toEqual(nodeString)

const imageMatches = execall(/\/_gatsby\/image/gm, updatedNodeString)
expect(imageMatches.length).toBe(39)


const transformedNodeStringNoHtmlImages = await replaceNodeHtmlImages({
nodeString,
node,
helpers: {
reporter: console
},
wpUrl: `http://wpgatsby.local/`,
pluginOptions: {
html: {
useGatsbyImage: false
}
}
})

expect(transformedNodeStringNoHtmlImages).toEqual(nodeString)

const noImageMatches = execall(/\/_gatsby\/image/gm, transformedNodeStringNoHtmlImages)

expect(noImageMatches.length).toBe(0)

expect(transformedNodeStringNoHtmlImages).not.toInclude(gatsbyImageUrl)
})
20 changes: 19 additions & 1 deletion packages/gatsby-source-wordpress/docs/plugin-options.md
Expand Up @@ -50,6 +50,7 @@
- [html.imageQuality](#htmlimagequality)
- [html.createStaticFiles](#htmlcreatestaticfiles)
- [html.generateWebpImages](#htmlgeneratewebpimages)
- [html.placeholderType](#htmlplaceholdertype)
- [type](#type)
- [type.\_\_all](#type__all)
- [type.\_\_all.where](#type__allwhere)
Expand All @@ -60,6 +61,7 @@
- [type.\_\_all.beforeChangeNode](#type__allbeforechangenode)
- [type.RootQuery](#typerootquery)
- [type.MediaItem](#typemediaitem)
- [type.MediaItem.placeholderSizeName](#typemediaitemplaceholdersizename)
- [type.MediaItem.createFileNodes](#typemediaitemcreatefilenodes)
- [type.MediaItem.lazyNodes](#typemediaitemlazynodes)
- [type.MediaItem.localFile](#typemediaitemlocalfile)
Expand Down Expand Up @@ -951,7 +953,7 @@ If a max width can't be inferred from html this value will be passed to Sharp. I

**Field type**: `Number`

**Default value**: `100`
**Default value**: `1024`

```js
{
Expand Down Expand Up @@ -1025,6 +1027,14 @@ When this is true, .webp images will be generated for images in html fields in a

```

### html.placeholderType

This can be either "blurred" or "dominantColor". This is the type of placeholder image to be used in Gatsby Images in HTML fields.

**Field type**: `String`

**Default value**: `blurred`

## type

Options related to specific types in the remote schema.
Expand Down Expand Up @@ -1179,6 +1189,14 @@ A special type which is applied to any non-node root fields that are ingested an

**Field type**: `Object`

#### type.MediaItem.placeholderSizeName

This option allows you to choose the placeholder size used in the new Gatsby image service (currently in ALPHA/BETA) for the small placeholder image. Please make this image size very small for better performance. 20px or smaller width is recommended. To use, create a new image size in WP and name it "gatsby-image-placeholder" (or the name that you pass to this option) and that new size will be used automatically for placeholder images in the Gatsby build.

**Field type**: `String`

**Default value**: `gatsby-image-placeholder`

#### type.MediaItem.createFileNodes

This option controls whether or not a File node will be automatically created for each MediaItem node (available on MediaItem.localFile). Set this to false if you don't want Gatsby to download the corresponding file for each media item.
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-source-wordpress/package.json
Expand Up @@ -31,6 +31,7 @@
"gatsby-core-utils": "^3.10.0-next.0",
"gatsby-plugin-catch-links": "^4.10.0-next.0",
"gatsby-source-filesystem": "^4.10.0-next.0",
"gatsby-plugin-utils": "^3.4.0-next.0",
"glob": "^7.2.0",
"got": "^11.8.3",
"lodash": "^4.17.21",
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby-source-wordpress/src/gatsby-node.ts
Expand Up @@ -37,6 +37,7 @@ module.exports = runApisInSteps({
],

onCreateDevServer: [
steps.imageRoutes,
steps.setImageNodeIdCache,
steps.logPostBuildWarnings,
steps.startPollingForContentUpdates,
Expand Down
6 changes: 6 additions & 0 deletions packages/gatsby-source-wordpress/src/models/gatsby-api.ts
Expand Up @@ -104,6 +104,7 @@ export interface IPluginOptions {
fallbackImageMaxWidth?: number
imageQuality?: number
createStaticFiles?: boolean
placeholderType?: `blurred` | `dominantColor`
}
presets?: Array<IPluginOptionsPreset>
type?: {
Expand All @@ -123,6 +124,8 @@ export interface IPluginOptions {
maxFileSizeBytes?: number
requestConcurrency?: number
}

placeholderSizeName?: string
}
}
}
Expand Down Expand Up @@ -191,6 +194,8 @@ const defaultPluginOptions: IPluginOptions = {
//
// this adds image options to images in HTML fields when html.useGatsbyImage is also set
gatsbyImageOptions: {},

placeholderType: `blurred`,
},
presets: [previewOptimizationPreset],
type: {
Expand Down Expand Up @@ -226,6 +231,7 @@ const defaultPluginOptions: IPluginOptions = {
exclude: true,
},
MediaItem: {
placeholderSizeName: `gatsby-image-placeholder`,
lazyNodes: false,
createFileNodes: true,
localFile: {
Expand Down
Expand Up @@ -7,6 +7,7 @@ import { getGatsbyNodeTypeNames } from "../source-nodes/fetch-nodes/fetch-nodes"
import { typeIsExcluded } from "~/steps/ingest-remote-schema/is-excluded"
import { formatLogMessage } from "../../utils/format-log-message"
import { CODES } from "../../utils/report"
import { addRemoteFilePolyfillInterface } from "gatsby-plugin-utils/polyfill-remote-file"

/**
* createSchemaCustomization
Expand Down Expand Up @@ -89,6 +90,20 @@ const customizeSchema = async ({ actions, schema }) => {
isAGatsbyNode: true,
})

typeDefs.push(
addRemoteFilePolyfillInterface(
schema.buildObjectType({
name: pluginOptions.schema.typePrefix + `MediaItem`,
fields: {},
interfaces: [`Node`, `RemoteFile`],
}),
{
schema,
actions,
}
)
)

typeDefs.push(wpType)

actions.createTypes(typeDefs)
Expand Down

0 comments on commit fe29c01

Please sign in to comment.