admin管理员组

文章数量:1279019

I use / 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;
});

I use http://github/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;
});
Share Improve this question edited Sep 27, 2018 at 20:05 fefe asked Sep 26, 2018 at 20:05 fefefefe 8943 gold badges14 silver badges34 bronze badges 6
  • Are you using the ACF to REST API plugin? – WebElaine Commented Sep 26, 2018 at 21:35
  • No I do not use any kind of plug in except acf – fefe Commented Sep 27, 2018 at 4:47
  • Maybe you should use register_meta() with show_in_rest set to true. Reference – Sally CJ Commented Sep 27, 2018 at 5:36
  • I tried thanks, but without any success – fefe Commented 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 Commented Sep 27, 2018 at 14:24
 |  Show 1 more comment

2 Answers 2

Reset to default 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/advanced-custom-fields-rest-api/

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

本文标签: Custom Post type with ACF in REST APIhow do I get those values