By default, Menus and Menu Items that are not assigned to a Menu Location are considered private, meaning they are not exposed in non-authenticated WPGraphQL Queries.
If you want to expose Menus and Menu Items that are not assigned to menu locations to public GraphQL Queries, you can use the following snippet:
The following snippets show how to change the Debug Flag for the GraphQL Server execution.
By default, the function callstack trace is not included with errors data unless users are logged in.
If you wanted to track this data on the server, for example, even for public requests, and send the data to a logging service, for example, you could enable the call stack with the following snippet. (Just make sure you _also_ cleanup the errors after the fact so you don’t expose too much data to public users.)
The following code is an example of how you can create a field called allUrls that will output site URLs that could be used to generate a sitemap.
The resolver uses mostly hard-coded data, but shows what a potential solution could look like.
add_action( 'graphql_register_types', function() {
register_graphql_field( 'RootQuery', 'allUrls', [
'type' => [ 'list_of' => 'String' ],
'description' => __( 'A list of all urls. Helpful for rendering sitemaps', 'your-textdomain' ),
'resolve' => function() {
// Start collecting all URLS
$meta_urls = array( get_home_url() );
// Hardcoded array. You would need to fetch the URLs for all Posts
$all_posts = [ 'site.com/post', 'site.com/post-2' ];
// Hardcoded array. You would need to fetch the URLs for all Terms
$all_terms = [ 'site.com/tag', 'site.com/category' ];
return array_merge($meta_urls, $all_posts, $all_terms);
}
] );
});
This is an example of registering a field with an argument showing how to use the argument in a resolver.
add_action( 'graphql_register_types', function() {
register_graphql_field( 'RootQuery', 'myNewField', [
'type' => 'String',
'args' => [
'myArg' => [
'type' => 'String',
'description' => __( 'Description for how the argument will impact the field resolver', 'your-textdomain' ),
],
],
'resolve' => function( $source, $args, $context, $info ) {
if ( isset( $args['myArg'] ) ) {
return 'The value of myArg is: ' . $args['myArg'];
}
return 'test';
},
]);
});
This will register a new field (myNewField ) to the RootQuery, and adds an argument to the field (myArg). The resolve function checks to see if that arg is set, and if so, it returns the value, if not it returns test.
We can query this like so:
query {
myNewField
}
And the results will be:
{
"data": {
"myNewField": "test"
}
}
Now, we can pass a value to the argument like so:
query {
myNewField( myArg: "something" )
}
and the results will be:
{
"data": {
"myNewField": "The value of myArg is: something"
}
}
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.
You can execute GraphQL queries in PHP. In this case, we even show using a GraphQL Fragment.
add_action( 'init', function() {
$results = graphql([
'query' => '
{
posts {
nodes {
...PostFields
}
}
}
fragment PostFields on Post {
id
title
}
',
]);
var_dump( $results );
die();
} );
Executing this code leads to the following output:
Additionally, if you were to define your fragment in another file, such as the file that is rendering the data, you can define fragments as variables and concatenate them like so:
$fragment = '
fragment PostFields on Post {
id
title
}
';
$results = graphql([
'query' => '
{
posts {
nodes {
...PostFields
}
}
}
' . $fragment ,
]);