Skip to content

Commit

Permalink
[gatsby-source-wordpress] add option for custom normalizer (#3450) (#…
Browse files Browse the repository at this point in the history
…5603)

* [gatsby-source-wordpress] add option for custom normalizer (#3450)

* [gatsby-source-wordpress] add documentation for custom normalizer (#3450)
  • Loading branch information
Fetten authored and pieh committed Jun 4, 2018
1 parent 31d8b0e commit a0cb081
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
53 changes: 53 additions & 0 deletions packages/gatsby-source-wordpress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ plugins: [
// Example: `["/*/*/comments", "/yoast/**"]` will exclude routes ending in `comments` and
// all routes that begin with `yoast` from fetch.
excludedRoutes: ["/*/*/comments", "/yoast/**"],
// use a custom normalizer which is applied after the built-in ones.
normalizer: function({ entities }) {
return entities;
},
},
},
];
Expand Down Expand Up @@ -503,6 +507,55 @@ To learn more about image processing check
* documentation of [gatsby-plugin-sharp](/packages/gatsby-plugin-sharp/),
* source code of [image processing example
site](https://github.com/gatsbyjs/gatsby/tree/master/examples/image-processing).

### Using a custom normalizer

The plugin uses the concept of normalizers to transform the json data from WordPress into
GraphQL nodes. You can extend the normalizers by passing a custom function to your `gatsby-config.js`.

#### Example:

You have a custom post type `movie` and a related custom taxonomy `genre` in your WordPress site. Since
`gatsby-source-wordpress` doesn't know about the relation of the two, we can build an additional normalizer function to map the movie GraphQL nodes to the genre nodes:

```javascript
function mapMoviesToGenres({ entities }) {
const genres = entities.filter(e => e.__type === `wordpress__wp_genre`);

return entities.map(e => {
if (e.__type === `wordpress__wp_movie`) {
let hasGenres = e.genres && Array.isArray(e.genres) && e.categories.length;
// Replace genres with links to their nodes.
if (hasGenres) {
e.genres___NODE = e.genres.map(c => genres.find(gObj => c === gObj.wordpress_id).id);
delete e.genres;
}
}
return e;
});

return entities;
}
```

In your `gatsby-config.js` you can then pass the function to the plugin options:

```javascript
module.exports = {
plugins: [
{
resolve: 'gatsby-source-wordpress',
options: {
// ...
normalizer: mapMoviesToGenres,
},
},
],
};
```

Next to the entities, the object passed to the custom normalizer function also contains other helpful Gatsby functions
and also your `wordpress-source-plugin` options from `gatsby-config.js`. To learn more about the passed object see the [source code](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-source-wordpress/src/gatsby-node.js).

## Site's `gatsby-node.js` example

Expand Down
29 changes: 29 additions & 0 deletions packages/gatsby-source-wordpress/src/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ let _auth
let _perPage
let _concurrentRequests
let _excludedRoutes
let _normalizer

exports.sourceNodes = async (
{ boundActionCreators, getNode, store, cache, createNodeId },
Expand All @@ -32,6 +33,7 @@ exports.sourceNodes = async (
searchAndReplaceContentUrls = {},
concurrentRequests = 10,
excludedRoutes = [],
normalizer,
}
) => {
const { createNode, touchNode } = boundActionCreators
Expand All @@ -43,6 +45,7 @@ exports.sourceNodes = async (
_perPage = perPage
_concurrentRequests = concurrentRequests
_excludedRoutes = excludedRoutes
_normalizer = normalizer

let entities = await fetch({
baseUrl,
Expand Down Expand Up @@ -112,6 +115,32 @@ exports.sourceNodes = async (
searchAndReplaceContentUrls,
})

// apply custom normalizer
if (typeof _normalizer === `function`) {
entities = _normalizer({
entities,
store,
cache,
createNode,
createNodeId,
touchNode,
getNode,
typePrefix,
refactoredEntityTypes,
baseUrl,
protocol,
_siteURL,
hostingWPCOM,
useACF,
auth,
verboseOutput,
perPage,
searchAndReplaceContentUrls,
concurrentRequests,
excludedRoutes,
})
}

// creates nodes for each entry
normalize.createNodesFromEntities({ entities, createNode })

Expand Down

0 comments on commit a0cb081

Please sign in to comment.