Using GraphQL Queries in PHP within your WordPress Theme or Plugin

GraphQL is most popularly known as a way to fetch data from remote sources via HTTP requests, but with WPGraphQL, you can access your local WordPress data in your plugin or theme via declarative GraphQL queries. An example use case would be a simple shortcode for a list of posts.

Example shortcode that outputs a list of posts and is populated with the site’s content with a GraphQL query

Let’s look at how we can build a simple shortcode that populates a list of posts from the site and renders an unordered list with the post’s title and date. First, lets register our shortcode:

add_shortcode( 'graphql_basic_post_list', function( $atts ) {
  return ! empty ( $output ) ? $output : '';
} );

Now we have a [graphql_basic_post_list] shortcode but it’s not useful. Our end goal is to output a list of posts with the title and date, and we’ll use the ID as the “id” of each list item. Since we know what data we’ll need, we can start with writing our GraphQL query to get the data. Inside the shortcode function, let’s add our query. GraphQL queries are static strings, so we can simply add:

$query = '
query basicPostList($first:Int){
   posts(first:$first){
      edges{
         node{
            id
            title
            date
         }
      }
   }
}
';

$data = do_graphql_request( $query );

This will give us an array of posts, which contains an array of “edges” and each edge will contain a “node”. The node is our post object, and this is where the fields we requested are. In our case, we asked for idtitle, and date. The raw data returned from the query should look like this (of course with your site’s data):

[data] => Array (
	[posts] => Array (
		[edges] => Array (
			[0] => Array (
				[node] => Array (
					[id] => cG9zdDoyOTI0
					[title] => Test GraphQL Basic Post List
					[date] => 2017-08-19 14:49:25
                )
            )
            [1] => Array (
				[node] => Array (
					[id] => cG9zdDoyOTE3
					[title] => Test Color Field
					[date] => 2017-08-11 19:42:10
                    )
                )
            [2] => Array (
				[node] => Array (
					[id] => cG9zdDoyODc0
					[title] => Denverpost Content in Gutenberg
					[date] => 2017-08-04 21:22:17
                )
            )
            [3] => Array (
				[node] => Array (
					[id] => cG9zdDoyNDA3
					[title] => Fieldmanager Test, yo
					[date] => 2017-06-28 16:25:13
                )
            )
            [4] => Array (
				[node] => Array (
					[id] => cG9zdDoyMzg2
					[title] => Testing a Gutenburg(sp?) Post
					[date] => 2017-06-23 21:02:57
                )
            )
        )
    )
)

This data looks pretty easy to work with! Now we just need to loop through the data and return our markup.

$edges = ! empty( $data['data']['posts']['edges'] ) ? $data['data']['posts']['edges'] : [];

if ( ! empty( $edges ) && is_array( $edges ) ) {
   $output = '
    '; foreach ( $edges as $edge ) { $node = ! empty( $edge['node'] ) ? $edge['node'] : ''; if ( ! empty( $node ) && is_array( $node ) ) { $output .= '
  • ' . $node['title'] . ' ' . $node['date'] . '
  • '; } } $output .= '
'; }

This makes sure that we have an array of “edges” and if we do, it creates an unordered list and loops through the edges, creating a list item for each node, with the node’s id as the <li> id property, and the post’s title and date as the text within the list item. The complete shortcode, with an example argument for how many posts to query is:

add_shortcode( 'graphql_basic_post_list', function( $atts ) {
   $query = '
   query basicPostList($first:Int){
      posts(first:$first){
         edges{
            node{
               id
               title
               date
            }
         }
      }
   }
   ';

   $variables = [
      'first' => ! empty( $atts['first'] ) ? absint( $atts['first'] ) : 5,
   ];

   $data = do_graphql_request( $query, 'basicPostList', $variables );

   $edges = ! empty( $data['data']['posts']['edges'] ) ? $data['data']['posts']['edges'] : [];

   if ( ! empty( $edges ) && is_array( $edges ) ) {
      $output = '
    '; foreach ( $edges as $edge ) { $node = ! empty( $edge['node'] ) ? $edge['node'] : ''; if ( ! empty( $node ) && is_array( $node ) ) { $output .= '
  • ' . $node['title'] . ' ' . $node['date'] . '
  • '; } } $output .= '
'; } return ! empty( $output ) ? $output : ''; });

NOTE: this post was written using Gutenberg v0.9.0

Published by Jason Bahl

Jason is a Principal Software Engineer at WP Engine based in Denver, CO where he maintains WPGraphQL. When he's not writing code or evangelizing about GraphQL to the world, he enjoys escaping from escape rooms, playing soccer, board games and Fortnite.

Leave a comment

Your email address will not be published. Required fields are marked *