NEW! WPGraphQL for Advanced Custom Fields

Interact with ACF Field data using GraphQL Queries

Query posts based on Advanced Custom Field values by Registering a Custom “where” Argument

If you manage custom fields in WordPress using Advanced Custom Fields, and you want to use WPGraphQL to get a list of posts filtering by the ACF field value, you’ll need to implement a few things in your themes functions.php.

Summary:

  • Register a new “where” argument to the WPGraphQL Posts connection
  • Filter the Posts connection resolver to account for this new argument

Register the new “where” argument:

First you need to create a add_action on graphql_register_types that will look something like the following code snippet. Here we register a field on the RootQueryToMyCustomPostTypeConnectionWhereArgs where you can define MyCustomPostType as your post type. The type we register will be an ID (This can also be of type Boolean, Float, Integer, orString) for my case I wanted to get only posts that where connected to an other post via the ACF post object field (the field was set to return only the Post ID).

Filter the connection resolver

add_action('graphql_register_types', function () {

    $customposttype_graphql_single_name = "MyCustomPostType";

    register_graphql_field('RootQueryTo' . $customposttype_graphql_single_name . 'ConnectionWhereArgs', 'postObjectId', [
        'type' => 'ID',
        'description' => __('The ID of the post object to filter by', 'your-textdomain'),
    ]);
});

Next we have to create an add_filter to graphql_post_object_connection_query_args. If you are familiar with WordPress loops via WP_Query, here we set the $query_args like we would do on any other loop, but we check for your custom where:.

add_filter('graphql_post_object_connection_query_args', function ($query_args, $source, $args, $context, $info) {

    $post_object_id = $args['where']['postObjectId'];

    if (isset($post_object_id)) {
        $query_args['meta_query'] = [
            [
                'key' => 'myCustomField',
                'value' => $post_object_id,
                'compare' => '='
            ]
        ];
    }

    return $query_args;
}, 10, 5);

The key will be the name of the field, the value will be the value you will give the postObjectId: "123" in your query, speaking of the query that will ook something like

query GetMyCustomPostType {
  MyCustomPostType(where: {postObjectId: "123"}) {
    nodes {
      title
    }
  }
}

This will get all your MyCustomPostType where myCustomField = 123

Share on facebook
Facebook
Share on google
Google+
Share on twitter
Twitter
Share on linkedin
LinkedIn
Share on pinterest
Pinterest

10 Replies to “Query posts based on Advanced Custom Field values by Registering a Custom “where” Argument”

  1. Jordan McDonald April 16, 2020 at 5:22 AM

    Hi, thanks for the post. It doesn’t work for me however. Do I need a certain version of WP Graph GL and WordPress?

    Thanks

    Reply

    1. When writing this I’d version `0.3.1` wp-graphql-acf and version `0.8.2` of wp-graphql (just updated to `0.8.3` with its still working). What does your code look like and what do you get while querying your data? Can you share your end-point with the query that is not working?

      Reply

      1. Jordan McDonald April 16, 2020 at 8:01 AM

        Here is the endpoint: https://wipaffirmadev.trafficmanager.net/graphql (it has an SSL issue so you will have to proceed past the warning). The error is
        {
        “errors”: [
        {
        “message”: “Field \”eventAudience\” is not defined by type RootQueryToEventConnectionWhereArgs.”,
        “category”: “graphql”,
        “locations”: [
        {
        “line”: 2,
        “column”: 18
        }
        ]
        }
        ]

        The code is below. My custom field is called event_audience in WordPress settings. My field group is called insiderEvent and that is showing up in the Graphiql explorer. I see eventAudience is listed there too but in wordPress it is event_audience. I have tried both in the code below as the “kye” but neither work.

        add_action(‘graphql_register_types’, function () {

        $customposttype_graphql_single_name = “event”;

        register_graphql_field(‘RootQueryTo’ . $customposttype_graphql_single_name . ‘ConnectionWhereArgs’, ‘eventAudience’, [
        ‘type’ => ‘string’,
        ‘description’ => __(‘The eventAudience of the Event custom post to filter by’, ‘Event’),
        ]);
        });

        add_filter(‘graphql_post_object_connection_query_args’, function ($query_args, $source, $args, $context, $info) {

        $post_object_id = $args[‘where’][‘eventAudience’];

        if (isset($post_object_id)) {
        $query_args[‘meta_query’] = [
        [
        ‘key’ => ‘eventAudience’,
        ‘value’ => $eventAudience,
        ‘compare’ => ‘=’
        ]
        ];
        }

        return $query_args;
        }, 10, 5);

        Reply

        1. What is the `graphql_single_name` on your custom post type Event? Is it `event` or is it `Event`?

          Reply

          1. Jordan McDonald April 16, 2020 at 8:23 AM

            This is what I have:
            ‘graphql_single_name’ => ‘event’,
            ‘graphql_plural_name’ => ‘events’,

  2. Jordan McDonald April 16, 2020 at 8:24 AM

    Tried this query:

    query MyQuery {
    events(where: {eventAudience: “PUBLIC”}) {
    edges {
    node {
    insiderEvent {
    eventAudience
    eventCity
    eventCtaAriaLabel
    eventDescription
    eventEndDate
    eventImageAltText
    eventIsGlobal
    eventRegistrationLink
    eventRegistrationLinkText
    eventStartDate
    fieldGroupName
    }
    }
    }
    }
    }

    Reply

  3. Jordan McDonald April 16, 2020 at 1:10 PM

    The custom field is of type SELECT. Is this ok? I am registering it as a string in ‘register_graphql_field’ because the output would be a string after a value has been selected.

    I had some issues with the code above and fixed something. Currently what I am trying is.

    add_action(‘graphql_register_types’, function () {

    $customposttype_graphql_single_name = “event”;

    register_graphql_field(‘RootQueryTo’ . $customposttype_graphql_single_name . ‘ConnectionWhereArgs’, ‘eventAudience’, [
    ‘type’ => ‘String’,
    ‘description’ => __(‘The eventAudience of the Event custom post to filter by’, ‘Event’),
    ]);
    });

    add_filter(‘graphql_post_object_connection_query_args’, function ($query_args, $source, $args, $context, $info) {

    $eventAudienceName = $args[‘where’][‘eventAudience’];

    if (isset($eventAudienceName)) {
    $query_args[‘meta_query’] = [
    [
    ‘key’ => ‘eventAudience’,
    ‘value’ => $eventAudienceName,
    ‘compare’ => ‘=’
    ]
    ];
    }

    return $query_args;
    }, 10, 5);

    Reply

  4. Jordan McDonald April 16, 2020 at 7:54 PM

    Resolved it. Was my issue. Thanks!

    Reply

    1. Can you share with us please ?

      Reply

      1. It probably was the fact that the types are typed with a capital letter at first so it is Boolean, Float, Integer, String not boolean, float, integer, string

        Reply

Leave a Reply

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