4

This is follow up question on Querying wordpress with meta queries from Gatsby

After a bit debugging I've gathered, and please correct me if I'm wrong, that Gatsby on build downloads the entire data structure and caches it. So all the GraphQL queries are performed against the cache. This makes all adjustments I try to make to wordpress (for example https://www.wpgraphql.com/2020/04/14/query-posts-based-on-advanced-custom-field-values-by-registering-a-custom-where-argument/) useless. I'm confined to using the filter argument for my GraphQL queries in Gatsby.

Consider the following query:

query Test {
  allWpPage(filter: {pagesGeo: {}}) {
    edges {
      node {
        pagesGeo {
          genericPage {
            ... on WpPage {
              id
            }
          }
          hreflangValue
        }
      }
    }
  }
}

In this case I want to filter on genericPage, but it's not in the list of available filters in the GraphiQL query tester.

In Wordpress the custom field generic_page is defined with the help of advanced custom fields and it's of the field type 'Post Object'. As you can see I'm able to query the field just fine, and it would be easy for me to create a meta query in Wordpress to filter on the field. It would looks something like:

$query_args['meta_query'] = [
    "relation" => "OR",
    [
        'key' => 'generic_page',
        'value' => $postObjectId,
        'compare' => '='
    ],
    [
        'key' => 'generic_page',
        'value' => $postObjectId2,
        'compare' => '='
    ],
];

Is there a way to make it possible for me to filter on genericPage in Gatsby?

If not, are there any alternative solutions for me to extract the data I need?

Borje
  • 255
  • 5
  • 19
  • Since you are using ACF for fields you will need this - https://www.wpgraphql.com/acf/ . As an additional note, don't forget to go to check Show in GraphQL at the very bottom of the ACF page when editing your custom fields. Read this for more info - https://stackoverflow.com/questions/63647590/gatsby-how-do-you-get-acf-advanced-custom-fields-to-work-with-gatsby-source – Snuffy Sep 01 '21 at 09:01
  • @MartinMirchev Thanks for the answer. I have the plugin and the field is shown in GraphQL. As you can see from my schema, the GenericPage field can be selected. However, I can't filter on it. Might be that it's not perceived as a node? – Borje Sep 01 '21 at 09:13
  • I think you must register the argument first. https://www.wpgraphql.com/2020/04/14/query-posts-based-on-advanced-custom-field-values-by-registering-a-custom-where-argument/ – Snuffy Sep 01 '21 at 10:56
  • @MartinMirchev If you look at my linked question you can see that a "where"-filter is restricted in Gatsby. But, as far as I can gather, Gatsby downloads all the data during build and then runs the GraphQL-queries on that cache. So if I register a new where argument in Wordpress, that won't affect the queries in Gatsby. If you have been able to do this, please provide a code example so that I can try and mimic it. – Borje Sep 01 '21 at 11:49

1 Answers1

5

After a bit debugging I've gathered, and please correct me if I'm wrong, that Gatsby on build downloads the entire data structure and caches it. So all the GraphQL queries are performed against the cache.

Yes, that's correct.

And I don't know much about Gatsby or GraphQL coding, but this is what I did and it worked quite well for me:

  1. I created a Gatsby site using the "WordPress blog" starter: https://github.com/gatsbyjs/gatsby-starter-wordpress-blog

  2. Then on my WordPress site, I installed these plugins: ACF (free version, v5.10.2), WP Gatsby v1.1.3, WP GraphQL v1.6.4, "WPGraphQL for Advanced Custom Fields" v0.5.3, and (just for testing) WPGraphQL Meta Query v0.1.0

  3. Then I created an ACF field group named "Pages GEO":

    • In the GraphQL meta box, I set "Show in GraphQL" to "Yes" and then I set "GraphQL Field Name" to pagesGeo (which is what you used, right?)

    • Then I created a Post Object field named "Generic Page" (generic_page) and then I set "Show in GraphQL" to "Yes"

  4. And then of course, I created/edited some Pages (i.e. post type page) and then selected a "Generic Page" for those Pages.

So regarding this:

In this case I want to filter on genericPage, but it's not in the list of available filters in the GraphiQL query tester.

I was not able to add filter.pagesGeo.genericPage, but I managed to filter by that field (i.e. filter.genericPage) by doing this:

I registered my very own custom WP GraphQL field named genericPage

  1. In my theme functions.php, I added:

    • The code is based on the one here.
    add_action( 'graphql_register_types', function() {
        register_graphql_field( 'Page', 'genericPage', [
            'type'        => 'Integer',
            'description' => 'generic_page meta value',
            'resolve'     => function( \WPGraphQL\Model\Post $post ) {
                return (int) get_post_meta( $post->databaseId, 'generic_page', true );
            }
        ] );
    });
    
  2. Then in GraphiQL IDE (at http://localhost:8000/__graphql), I ran this query:

    Screenshot

    • So in the above query, I filtered the posts by the generic_page meta, where I queried for posts where the meta value (i.e. the post ID, or databaseId in GraphQL) is 2 or 82.

    • And I used the in comparator, but you could just use any other comparator that suits your query. See https://www.gatsbyjs.com/docs/query-filters/#supported-comparators

  3. And the result was:

    Screenshot 2

    • So as you could see, for each node/post (in data.allWpPage.nodes), the root genericPage matches the pagesGeo.genericPage.databaseId.

Additional Notes

I used the gatsby develop command which (if I was not mistaken) rebuilds the cache, but if necessary, the cache can be cleared manually — see https://www.gatsbyjs.com/docs/build-caching/#clearing-cache.

Sally CJ
  • 15,362
  • 2
  • 16
  • 34
  • 1
    This was just the kind of workaround I was looking for, and a great explanatory answer. Two thumbs up and bounty rewarded. Sidenote: I was using the same plugins as you plugins as you mentioned. It does seem like you should be able to do a "filter.pagesGeo.genericPage" but somewhere there's a bug. I might issue a bug report with the `gatsby-source-wordpress`-plugin. Thank you for you help. – Borje Sep 05 '21 at 22:10
  • Thank you so much for this. How would I modify this to filter by a custom field on the post object? I'm not working with Pages. I've tried register_graphql_field('Post', 'clientId') but no luck... – Sean H Feb 09 '23 at 11:13