Tag: Custom Post Types

  • Add Edit Link to All Post Types

    The following snippet shows how to add the “Edit” link as a GraphQL field to all post types:

    add_action( 'graphql_register_types', function() {
    
    	register_graphql_field( 'ContentNode', 'editLink', [
    		'type' => 'String',
    		'description' => __( 'Link to edit the content', 'your-textdomain' ),
    		'resolve' => function( \WPGraphQL\Model\Post $post, $args, $context, $info ) {
    		   return get_edit_post_link( $post->databaseId );
    		}
    	]);
    
    } );

    This could then be queried like so:

    Screenshot of a GraphQL Query for posts with their editLink
    Screenshot of a GraphQL Query for posts with their editLink
  • Register Connection to Attached Media

    This code shows how to register a connection to attached media in WPGraphQL

    add_action( 'graphql_register_types', function() {
    
    	register_graphql_connection([
    		'fromType' => 'ContentNode',
    		'toType' => 'MediaItem',
    		'fromFieldName' => 'attachedMedia',
    		'connectionArgs' => \WPGraphQL\Connection\PostObjects::get_connection_args(),
    		'resolve' => function( \WPGraphQL\Model\Post $source, $args, $context, $info ) {
    			$resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver( $source, $args, $context, $info, 'attachment' );
    			$resolver->set_query_arg( 'post_parent', $source->ID );
    			return $resolver->get_connection();
    		}
    	]);
    
    } );

    You can then query for this new connection using the attachedMedia field on a ContentNode:

    {
      contentNodes {
        nodes {
          ... on NodeWithTitle {
            title
          }
          attachedMedia {
            nodes {
              id
              title
            }
          }
        }
      }
    }
  • Register object and field for custom list of users

    The following code creates an object type called StuntPerformer and creates a field on the RootQuery called stuntPerformers that returns a custom list of users.

    In this case, the list of users are the admins of the website, but custom logic could be added to return a curated list of users.

    add_action( 'graphql_register_types', function() {
    
    	register_graphql_object_type(
    		'StuntPerformer',
    		[
    			'description' => __( 'Stunt Performer', 'bsr' ),
    			'fields'      => [
    				'firstName' => [
    					'type'        => 'String',
    					'description' => 'first name'
    				],
    				'lastName'  => [
    					'type'        => 'String',
    					'description' => 'last name'
    				],
    				'uid'       => [
    					'type'        => 'String',
    					'description' => 'user id'
    				]
    			],
    		]
    	);
    
    	register_graphql_field(
    		'RootQuery',
    		'stuntPerformers',
    		[
    			'description' => __( 'Return stunt performers', 'bsr' ),
    			'type'        => [ 'list_of' => 'stuntPerformer' ],
    			'resolve'     => function() {
    				$stunt_performers = [];
    				$performers       = get_users( array(
    					'role__in' => 'administrator'
    				) );
    
    				foreach ( $performers as $p ) {
    					$performer = [
    						'firstName' => $p->first_name,
    						'lastName'  => $p->last_name,
    						'uid'       => $p->ID
    					];
    
    					$stunt_performers[] = $performer;
    				}
    
    				return $stunt_performers;
    			}
    		]
    	);
    
    } );

    You can now query for these stuntPerformers with the following GraphQL:

    {
      stuntPerformers {
        firstName
        lastName
        uid
      } 
    }
    Stunt Performers query in GraphiQL
  • Tag to Content Node Connection

    The following code registers a connection from Tags to ContentNodes. A field name called contentNodes will be added to the Tag type to make it easy to view all Posts that are tagged with that specific term.

    add_action( 'graphql_register_types', function() {
    	register_graphql_connection([
    		'fromType' => 'Tag',
    		'toType' => 'ContentNode',
    		'fromFieldName' => 'contentNodes',
    		'resolve' => function( \WPGraphQL\Model\Term $source, $args, $context, $info ) {
    			// Get all post types allowed in GraphQL
    			$post_types = WPGraphQL::get_allowed_post_types();
    
    			// Instantiate a new PostObjectConnectionResolver class
    			$resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver( $source, $args, $context, $info, $post_types );
    
    			// Set the argument that will be passed to WP_Query. We want only Posts (of any post type) that are tagged with this Tag's ID
    			$resolver->set_query_arg( 'tag_id', $source->term_id );
    
    			// Return the connection
    			return $resolver->get_connection();
    		}
    	]);
    } );
  • List of Key Values

    This is an example showing how to return a list of keys and values where the keys and values are both strings.

    add_action( 'graphql_register_types', function() {
    
    	register_graphql_object_type( 'keyValue', [
    		'description' => __( 'Keys and their values, both cast as strings', 'your-textdomain' ),
    		'fields'      => [
    			'key'   => [
    				'type' => 'String',
    			],
    			'value' => [
    				'type' => 'String',
    			],
    		]
    	] );
    
    	register_graphql_field( 'RootQuery', 'listOfKeyValues', [
    		'type'        => [ 'list_of' => 'KeyValue' ],
    		'description' => __( 'Field that resolves as a list of keys and values', 'your-textdomain' ),
    		'resolve'     => function() {
    			$mock_array = [
    				'key1' => 'Value1',
    				'key2' => 'Value2',
    				'key3' => 'Value3'
    			];
    
    			$list = [];
    			foreach ( $mock_array as $key => $value ) {
    				$list[] = [
    					'key' => $key,
    					'value' => $value,
    				];
    			}
    
    			return $list;
    		}
    	] );
    
    } );
  • Popular Posts

    The following code allows you to query for popular posts. It’s still up to you to determine the best way to store popular posts, but this example assumes a meta_key is involved. Beware though, meta queries can be expensive!

    add_action( 'graphql_register_types', function() {
    
    	// This registers a connection to the Schema at the root of the Graph
    	// The connection field name is "popularPosts"
    	register_graphql_connection( [
    		'fromType'           => 'RootQuery',
    		'toType'             => 'Post',
    		'fromFieldName'      => 'popularPosts', // This is the field name that will be exposed in the Schema to query this connection by
    		'connectionTypeName' => 'RootQueryToPopularPostsConnection',
    		'connectionArgs'     => \WPGraphQL\Connection\PostObjects::get_connection_args(), // This adds Post connection args to the connection
    		'resolve'            => function( $root, $args, \WPGraphQL\AppContext $context, $info ) {
    
    			$resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver( $root, $args, $context, $info );
    
    			// Note, these args will override anything the user passes in as { where: { ... } } args in the GraphQL Query
    			$resolver->set_query_arg( 'meta_key', 'wpb_post_views_count' );
    			$resolver->set_query_arg( 'orderby', 'meta_value_num' );
    			$resolver->set_query_arg( 'order', 'DESC' );
    
    			return $resolver->get_connection();
    		}
    	] );
    
    	// This registers a field to the "Post" type so we can query the "viewCount" and see the value of which posts have the most views
    	register_graphql_field( 'Post', 'viewCount', [
    		'type'    => 'Int',
    		'resolve' => function( $post ) {
    			return get_post_meta( $post->databaseId, 'wpb_post_views_count', true );
    		}
    	] );
    
    } );

    You can query for the popular posts using this GraphQL query:

    {
      popularPosts(first: 10, where: {dateQuery: {after: {year: 2021, month: 10}}}) {
        nodes {
          id
          title
          date
          viewCount
        }
      }
    }