skip to Main Content

WordFlix – Single Page App tutorial: Step 9 – Customize the GraphQL Schema

Post Series: WordFlix – Super Powered Single Page App Tutorial

Step 9 – Starting Point

  • If you followed the previous steps of the tutorial, you should be able to continue here, but if you’re just jumping in or got lost in the last steps or just want to skip ahead, you can either check-out this branch of the Github repo or change directories to the “8” theme (wp-content/themes/8)

Filter the “post” Schema

Previously we left a placeholder in the MoviePage component for the release date. In this step, we add the releasedDate as a field to the “posts” schema via a filter in our “inc/graphql.php” file.
In “inc/graphql.php” add the following code:

use WPGraphQL\Types;

add_filter( 'graphql_post_fields', function( $fields ) {

	$fields['releaseDate'] = [
		'type'        => Types::string(),
		'description' => __( 'The date the film was released', 'graphql-workshop' ),
		'resolve'     => function( \WP_Post $post, array $args, \WPGraphQL\AppContext $context, \GraphQL\Type\Definition\ResolveInfo $info ) {

			$release_date = get_post_meta( $post->ID, 'release_date', true );
			$timestamp    = strtotime( $release_date );

			return ( false !== $timestamp ) ? date( 'M j, Y', $timestamp ) : null;
		},
	];

	return $fields;

}, 10, 1 );

This filters the fields for the “post” type in our GraphQL schema and adds a “releaseDate” field.

In GraphQL, each field needs a type, description (optional, but recommended), and a resolve method (in some cases optional as well).

In our case, the “releaseDate” will return a string, so we set the type to use the string type already defined by the WPGraphQL plugin.

Then we give a description of the field.

In GraphQL, the resolve function gets 4 things passed to it: the object being resolved (in our case the WP_Post object, an array of $args on the field, the AppContext which provides details such as who the current user is, etc and the ResolveInfo which provides introspection into where in the query tree the current resolver is, what fields are being queried, and other potentially helpful data).

The only piece of context we’re concerned with now is the $post object. We use the $post->ID to look up the “release_date” post meta, then we convert it to a timestamp. We validate whether it’s actually a timestamp, and if so we return a date, otherwise we return null.

Now, we can see in GraphiQL that we have a “releaseDate” field in our posts schema, but only posts, not other postTypes, like pages.

 

Add Release Date to the MovieContent

Now, let’s update our query in the MoviePage.js file to add the “releaseDate” field

const movieQuery = gql`
    query getMovie($id:ID!){
      movie:post(id:$id){
        id
        title
        content
        releaseDate
        poster:featuredImage{
            url:sourceUrl
        }
      }
    }
`;

Then update the MoviePage component and replace our TBA placeholder for release date:

<MovieContent>
  <h2>{movie.title}</h2>
  <h3>Released: {movie.releaseDate}</h3><br/>
  <div dangerouslySetInnerHTML={ { __html: movie.content } } />
</MovieContent>

Now we’ve got our MovieDetail page rendering custom postmeta data that we added to our Schema!

Leave a Reply

Share This
Back To Top