/

Custom Fields and Meta

Learn about how to expose Custom Fields and Meta in the WPGraphQL Schema


WPGraphQL exposes an API to register fields to any Type in the Schema. We can use this API to register fields that expose custom fields, such as Post Meta, Term Meta, etc.

Let’s say we stored some meta called color on our docs Post Type and we wanted to expose this on our Document objects. We could do that like so:

add_action( 'graphql_register_types', function() {
  register_graphql_field( 'Post', 'color', [
     'type' => 'String',
     'description' => __( 'The color of the post', 'wp-graphql' ),
     'resolve' => function( $post ) {
       $color = get_post_meta( $post->ID, 'color', true );
       return ! empty( $color ) ? $color : 'blue';
     }
  ] );
} );
PHP Code SnippetsThe above PHP code snippet can be added to your WordPress Child Theme's functions.php file or other appropriate file such as a custom plugin that is active on your site.

Here, we hook into graphql_register_types as that’s when the GraphQL Type registry is being built and our registration methods are ready for use.

Then we call register_graphql_field, where the first argument is the Type we want to register the field to, in this case Post. The second argument is the name of the field, and the third argument is an array used to configure the field. For this config array we need at minimum a Type defined, in this case the type is String.

Here we also define a field description and a resolve function. If no resolve function is defined, GraphQL will attempt to resolve using the field name as the property of the object being passed down. We know that Post objects in WordPress don’t have a color property, so we need to tell GraphQL how to resolve color on Posts in the Schema. In our case, the data is in post_meta, so we tell GraphQL to resolve the color field by getting the color post_meta for the Post being resolved, and if there is no color returned, let’s just default to blue.

{
  posts {
    nodes {
      id
      link
      color
    }
  }
}

Register fields to many types

Let’s say we wanted to register the same color field to ALL Post Types that are exposed in the Schema.

We could to that like so:

add_action( 'graphql_register_types', function() {

  $post_types = \WPGraphQL::get_allowed_post_types();

  if ( ! empty( $post_types ) && is_array( $post_types ) ) {
    foreach ( $post_types as $post_type ) {
       $post_type_object = get_post_type_object( $post_type );

       register_graphql_field( $post_type_object->graphql_single_name, 'color', [
         'type' => 'String',
         'description' => __( 'The color of the post', 'wp-graphql' ),
         'resolve' => function( $post ) {
           $color = get_post_meta( $post->ID, 'color', true );
           return ! empty( $color ) ? $color : 'blue';
         }
      ] );

    }
  }
});
PHP Code SnippetsThe above PHP code snippet can be added to your WordPress Child Theme's functions.php file or other appropriate file such as a custom plugin that is active on your site.

Here, we hook once again into graphql_register_types.

From there, we access the list of Post Types that have been registered as allowed in WPGraphQL, then we loop through the list and register the color field to each Type, via the $post_type_object->graphql_single_name property.

Now, we can query the color field on ANY exposed Custom Post Type in our Schema.

{
  documents {
    nodes {
      id
      title
      link
      color
    }
  }
}

Register multiple fields, specifying type

If instead we want to register multiple fields (in this case blurb and price), but control which Post Types they are exposed to, we could do the following:

add_action( 'graphql_register_types', function() {

  $post_types = WPGraphQL::$allowed_post_types;

  if ( ! empty( $post_types ) && is_array( $post_types ) ) {
    foreach ( $post_types as $post_type ) {
			$post_type_object = get_post_type_object( $post_type );

			if ($post_type === 'post') {
				register_graphql_field( $post_type_object->graphql_single_name, 'blurb', [
					'type' => 'String',
					'description' => __( 'The blurb of the post', 'wp-graphql' ),
					'resolve' => function( $post ) {
						$blurb = get_post_meta( $post->ID, 'blurb', true );
						return ! empty( $blurb ) ? $blurb : 'blue';
					}
				]);
			}

			if ($post_type === 'product') {
				register_graphql_field( $post_type_object->graphql_single_name, 'price', [
					'type' => 'String',
					'description' => __( 'The price of the post', 'wp-graphql' ),
					'resolve' => function( $post ) {
						$price = get_post_meta( $post->ID, 'price', true );
						return ! empty( $price ) ? $price : 'blue';
					}
				]);
			}
    }
  }
});
PHP Code SnippetsThe above PHP code snippet can be added to your WordPress Child Theme's functions.php file or other appropriate file such as a custom plugin that is active on your site.

This is very similar to the example above, but we only add a given field if the proper Post Type is currently being looped over.

Resolving external (non-WordPress) data

Just because WPGraphQL exposes a lot of ways to interact with data stored in the WordPress database, resolvers allow data to be returned from any data source.

For example, we could make external API calls to other services such as Google Analytics, or whatever you could imagine, and resolve data from that API response from within GraphQL. We could even connect to any other database, or custom tables, static data, .csv files, etc. The potential is really quite expansive.

Take a look at the WPGraphQL Dad Jokes extension for an example of registering fields that resolve data from an external API.

Edit on GitHub

Custom Fields and Meta

Edit on GitHub

Discuss on Spectrum