Support

Account

Home Forums General Issues How to access ACF field in a custom WordPress Rest API endpoint?

Solved

How to access ACF field in a custom WordPress Rest API endpoint?

  • I have a Advanced Custom Fields FAQ repeater field that I’m trying to add FAQ’s to my custom search results, and am unable to get the field through the Rest API.

    I’m registering the endpoint like so:

    add_action('rest_api_init', 'register_search');
    function register_search() {
        register_rest_route('fralin/v1', 'search', array(
            'methods' => WP_REST_Server::READABLE,
            'callback' => 'search_results',
            'permission_callback' => '__return_true',
        ));
    }

    Which calls the Callback:

    
    function search_results($data) {
        $main_query = new WP_Query(array(
            'post_type' => array('product', 'post', 'page', 'diagram'), //Would grab FAQ as a custom post type, but it's not it's own custom post type - just custom fields on a page.
            'posts_per_page' => 18,
            'post_status' => 'publish',
            'order_by' => 'relevance',
            'order' => 'ASC',
            'no_found_rows' => true,
            's' => sanitize_text_field($data['term']),
        ));
    
        $results = array(
            'products' => array(),
            'pages' => array(),
            'posts' => array(),
            'diagrams' => array()
        );
    
        while ($main_query->have_posts()) {
            $main_query->the_post();
            global $product;
            global $post;
    
            if (get_post_type() == 'product') {
                array_push($results['products'], array(
                    'title' => $product->get_name(),
                    'link' => get_the_permalink(),
                    'featuredImage' => get_the_post_thumbnail_url(),
                    'sku' => $product->get_sku(),
                    'priceHTML' => $product->get_price_html(),
                    'tagline' => get_field('product_tagline', get_the_ID()),
                    'originalDesign' => get_field('original_design', get_the_ID()),
                    'productAttributes' => array(
                        get_field('pickup_design', get_the_ID()),
                        get_field('pickup_appearance', get_the_ID()),
                    ),
                ));
            }
    
            if (get_post_type() == 'post') {
                array_push($results['posts'], array(
                    'title' => get_the_title(),
                    'link' => get_the_permalink(),
                    'featuredImage' => get_the_post_thumbnail_url($post->ID, 'thumbnail'),
                    'publishedDate' => get_the_time('F j, Y'),
    
                ));
            }
    
            if (get_post_type() == 'page') {
                array_push($results['pages'], array(
                    'title' => get_the_title(),
                    'link' => get_the_permalink(),
                    'faq' => get_field('faqs'), // Trying to access FAQ Questions and Answers here.
                ));
            }
    
            if (get_post_type() == 'diagram') {
                array_push($results['diagrams'], array(
                    'title' => get_the_title(),
                    'thumbnail' => get_field('wiring_diagram_thumbnail')['sizes']['thumbnail'],
                    'pdf' => get_field('wiring_diagram_pdf'),
                    'description' => get_field('wiring_diagram_description')
                ));
            }
        }
    
        return $results;
    }

    I see why I’m unable to get access to the FAQ value. It’s searching the pages post type for any values search values, and none are there. FAQ’s are just added to a page template – not it’s own custom post type.

    That said, I’m totally lost on how to include ACF fields in search results.

    I want a user to search for “ice cream” and have my search function look for FAQ fields involving those keywords, and be able to return the question and answer in the search results. I’m just stuck at actually getting the values.

    Any ideas on where to start? Thank you.

  • This

    
    's' => sanitize_text_field($data['term']),
    

    only causes searching of the post title and post content.

    https://adambalee.com/search-wordpress-by-custom-fields-without-a-plugin/

    Before you read this. Adding a repeater to search is extremely difficult. You will need to search in meta_key LIKE "faq_%"

  • Thanks, John – I have a plugin installed ‘Better ACF Search’ to get the fields, and that seems to work as if I search for a unique keyword in one of the FAQ fields, I get the FAQ Page as a search result. I’m assuming that plugin is working at this because of that.

    My question now becomes, if I search in meta_key LIKE "faq_%", do I need a new WP_Query for those results, or can I amend my original query?

    I appreciate the help, I’m a little new at this and learning.

  • So is it working now using the plugin or not? The reason the plugin works is that it is adding a join and altering the where portion of the query as mentioned in the article I linked to.

    Without the plugin you don’t need a new query, but you do need to filter the query before it is run, as it shows in the article.

  • Testing the search queries for keywords unique to the FAQ questions/answers fields return the FAQ page, which I assume means that the plugin is working. If the search query is extending to a repeater field, it’s returning the parent page on which those fields are outputted.

    I’m confused on where to go next, and I appreciate your patience.

    The code in my original post is in a file called search-route.php. I’m assuming the filter you’re talking about in the article is the following:

    /**
     * Modify the search query with posts_where
     *
     * http://codex.wordpress.org/Plugin_API/Filter_Reference/posts_where
     */
    function cf_search_where( $where ) {
        global $pagenow, $wpdb;
    
        if ( is_search() ) {
            $where = preg_replace(
                "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
                "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
        }
    
        return $where;
    }
    add_filter( 'posts_where', 'cf_search_where' );

    Am I correct in thinking that this is the function I need to add to my search-route.php?

  • Okay, so I might have been confused. I was thinking that the query was not returning the pages with faqs in the results.

    Is it this part that is not working?

    
    faq' => get_field('faqs')
    

    Are the get_field() calls in the other post types working?

  • No problem! So, I was just playing around with this, and if I grab the fields on the parent field, I get All Fields and Sub Fields of the FAQ page.

    if (get_post_type() == 'page') {
                array_push($results['pages'], array(
                    'title' => get_the_title(),
                    'link' => get_the_permalink(),
                    'faq' => get_field('faq-topic'),
                ));
            }

    Here’s an example of a response:

    "faqs": [
                {
                  "faq_group": {
                       "question": "What are your shop hours?",
                       "answer": "<p><strong>Our shop hours:</strong></p>\n<ul>\n<li>Monday – Thursday: 10-6 PM EST</li>\n<li>Friday: 10-5 PM EST</li>\n<li>Saturday: Closed</li>\n<li>Sunday: Closed</li>\n</ul>\n",
                        "linked_page": ""
                                }
                  }],

    Where I’m really trying to go from here is to access both the question and answer and access them via javascript template literal, which I have working really well. All other post types and their respective fields are working nicely. I’m just struggling with this one.

  • I was just playing around with this, and if I grab the fields on the parent field

    This is the issue. What is the parent field type?

  • Hey John,

    It’s a Repeater Field. Check out the structure here:

    You’ll see the nested repeater, etc.

  • You are going to have to loop over that parent repeater and some how find the row you want to show. I’m not really sure how you would do this.

  • Yeah this is way out of my wheelhouse, and if you’re not sure how, I think I’ll just put a pin in this. It was worth the exploration. Thanks a lot for your assistance, John!

  • I don’t know what your are looking for? Are you looking for something that matches what was searched for? At what level/where in the repeater will you find what you want to show?

  • I’m looking to return both the question and the answer in a custom search overlay. For instance, if a customer types in “flavors”, I would like a dynamically populated “card” that has both the question and answer in it, for instance — Q: What flavors do you have? A: Strawberry, Chocolate, etc.

    I have the Javascript / card stuff taken care of, I just can’t seem to return both the Q and A which match a search term in the API.

  • Sorry for the late response.

    Basically what you need to do is to assign what you want to return to a varialble and then include that variable.

    
    if (get_post_type() == 'page') {
    $faq = '{assign values for faq}';
                array_push($results['pages'], array(
                    'title' => get_the_title(),
                    'link' => get_the_permalink(),
                    'faq' => $fag,
                ));
            }
    

    The problem is going finding the ones that you want because you need to search the sub fields the same way that wp searches the content.

    1. split the search string up into an array of words
    2. loop over the parent repeater
    3. loop over the sub repeater
    4. loop over the words in the search string
    5. test each sub field for the existence of $word
Viewing 14 posts - 1 through 14 (of 14 total)

You must be logged in to reply to this topic.