1

I use http://github.com/jjgrainger/PostTypes/ to register my custom post types and ACF to add custom fields to my custom post and I want to include in my wp-json response all registered fields per post and I do the following

$options = [
    'supports' => array('revisions'),
    'has_archive' => false,
    'show_in_rest' => true,
    'rewrite' => array('slug' => __('teachers', 'teachers')),
    'capability_type' => 'post',
    'rest_base' => 'teachers',
    'query_var' => true,
    'rest_controller_class' => 'WP_REST_Posts_Controller',
];
$teachers = new PostType('teacher', $options);
$locations = new Taxonomy('location');
$levels = new Taxonomy('level');

$teachers->filters(['first_name', 'last_name']);
$teachers->columns()->hide(['title', 'date']);

$teachers->columns()->add([
    'first_name' => __('First Name'),
    'last_name' => __('Last Name'),
]);

$teachers->taxonomy('location');
$teachers->taxonomy('level');

$teachers->columns()->populate('first_name', function ($column, $post_id) {
    echo get_post_meta($post_id, 'first_name')[0];
});

$teachers->columns()->populate('last_name', function ($column, $post_id) {
    echo get_post_meta($post_id, 'last_name')[0];
});

$levels->columns()->add([
    'level' => __('Level'),
]);

$levels->register();
$locations->register();
$teachers->register();

but in wp-json response I do not have any custom fields, than I tried after googling adding the following filter

function my_rest_prepare_post($data, $post, $request) {
    dd($data);
    $_data = $data->data;

    $fields = get_fields($post->ID);
    foreach ($fields as $key => $value){
        $_data[$key] = get_field($key, $post->ID);
    }
    $data->data = $_data;

    return $data;
}
add_filter("rest_prepare_teacher", 'my_rest_prepare_post', 10, 3);

but in this case I get a Fatal Error

Fatal error</b>:  Uncaught Error: Call to a member function get_links() on null in

How can I reflect in wp-json response on a custom post type all related custom field values?

Update

I forgot to mention that on top of wordpress I use wordplate with sage and after tracking down rest_prepare_{$post_type} method I got to this point, which is working in my case

add_filter("rest_prepare_teacher", function($post) {
    $_data = $post->data;
    $fields = get_fields($_data['id']);

    foreach ($fields as $key => $value){
        $_data[$key] = get_field($key, $_data['id']);
    }
    $post->data = $_data;
    return $post;
});
6
  • Are you using the ACF to REST API plugin?
    – WebElaine
    Sep 26, 2018 at 21:35
  • No I do not use any kind of plug in except acf
    – fefe
    Sep 27, 2018 at 4:47
  • Maybe you should use register_meta() with show_in_rest set to true. Reference
    – Sally CJ
    Sep 27, 2018 at 5:36
  • I tried thanks, but without any success
    – fefe
    Sep 27, 2018 at 7:05
  • Try the ACF to REST API plugin. It's built specifically to expose ACF fields in the REST API.
    – WebElaine
    Sep 27, 2018 at 14:24

2 Answers 2

2

I really hope that you have managed this issue. In case you don't, this kinda works for me since there is a way to register a custom acf endpoint, in the functions.php file you have to add the next code:

//Custom acf endpoint;
function my_endpoint( $request_data ) {

    // setup query argument
    $args = array(
        'post_type' => 'my_post_type',
        'posts_per_page' => -1
    );

    // get posts
    $posts = get_posts($args);

    // add custom field data to posts array 
    foreach ($posts as $key => $post) {
            $posts[$key]->acf = get_fields($post->ID);
            $posts[$key]->link = get_permalink($post->ID);
            $posts[$key]->image = get_the_post_thumbnail_url($post->ID);
    }
    return $posts;
}

// register the endpoint;
add_action( 'rest_api_init', function () {
    register_rest_route( 'my_endpoint/v1', '/my_post_type/', array(
        'methods' => 'GET',
        'callback' => 'my_endpoint',
        )
    );
}

Credits to: https://clarencepearson.com/advanced-custom-fields-rest-api/

0

This answer inspired me to find my solution - I wanted to post it here in case it helps someone in the future:

use WP_Post;
use WP_REST_Request;
use WP_REST_Response;

class PreparePostAcfData
{
    public function preparePostAcfData(WP_REST_Response $response, WP_Post $post, WP_REST_Request $request): WP_REST_Response
    {
        $data = $response->get_data();
        $fieldsData = get_fields($post->ID);
        if(is_array($data['acf']) && is_array($fieldsData)) {
            $data['acf'] = array_merge($data['acf'], $fieldsData);
        }
        $response->set_data($data);

        return $response;
    }
}

and then you can attach that to any custom post type using one of the wordpress rest api filters

$this->loader->add_filter('rest_prepare_advice_zone', $plugin_public->preparePostAcfData, 'preparePostAcfData', 99, 3);

The only thing to note really is that I had all ready defined $data['acf'] earlier in the request cycle but you could quite easily swap out the array check for if exists or whatever seems relevant. Have a read of the wordpress filter being used rest_prepare_POST_TYPE

cheers

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.