Why my admin doesn’t work after adding rest_prepare_post filter?

When I add a filter to custom get_all_posts API callback, API works, but the admin page for each page is blank. Why?

function get_all_posts( $data, $post, $context ) {

    return [
        'id'        => $data->data['id'],
        'date'      => $data->data['date'],
        'date_gmt'  => $data->data['date_gmt'],
        'modified'  => $data->data['modified'],
        'title'     => $data->data['title']['rendered'],
        'content'   => $data->data['content']['rendered'],
        'main_text' => $data->data['main_text'],
        'featured_media_url'   => $data->data['jetpack_featured_media_url'],
        'category'  => get_the_category_by_ID( $data->data['categories'][0] ),
        'link'      => $data->data['link']
    ];
}

add_filter( 'rest_prepare_post', 'get_all_posts', 10, 3 );

EDIT:
Got this error on the webpage Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'e.length')

enter image description here

FYI: I added a meta box on the post admin page, the meta box works perfectly without the code above.

My entire code:

function main_text_meta_box() {

    add_meta_box(
        'main-text',
        __( 'Main text', 'sitepoint' ),
        'main_text_meta_box_callback',
        'post'
    );
}

function main_text_meta_box_callback( $post ) {

    // Add a nonce field so we can check for it later.
    wp_nonce_field( 'main_text_nonce', 'main_text_nonce' );

    $value = get_post_meta( $post->ID, '_main_text', true );

    echo '<textarea style="width:100%; height:300px;" id="main_text" name="main_text">' . esc_attr( $value ) . '</textarea>';
}

add_action( 'add_meta_boxes', 'main_text_meta_box' );


function save_main_text_meta_box_data( $post_id ) {

    // Check if our nonce is set.
    if ( ! isset( $_POST['main_text_nonce'] ) ) {
        return;
    }

    // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $_POST['main_text_nonce'], 'main_text_nonce' ) ) {
        return;
    }

    // If this is an autosave, our form has not been submitted, so we don't want to do anything.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }

    // Check the user's permissions.
    if ( isset( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {

        if ( ! current_user_can( 'edit_page', $post_id ) ) {
            return;
        }

    }
    else {

        if ( ! current_user_can( 'edit_post', $post_id ) ) {
            return;
        }
    }

    /* OK, it's safe for us to save the data now. */

    // Make sure that it is set.
    if ( ! isset( $_POST['main_text'] ) ) {
        return;
    }

    // Sanitize user input.
    $my_data = sanitize_text_field( $_POST['main_text'] );

    // Update the meta field in the database.
    update_post_meta( $post_id, '_main_text', $my_data );
}
add_action( 'save_post', 'save_main_text_meta_box_data' );

function add_custom_fields() {
    register_rest_field(
         'post', 
         'main_text', //New Field Name in JSON RESPONSEs
         array(
          'get_callback'    => 'get_main_text', // custom function name 
          'update_callback' => null,
          'schema'          => null,
        )
    );
}
add_action( 'rest_api_init', 'add_custom_fields' );


function get_main_text ( $post, $field_name, $request ){

        return get_post_meta($post['id'], '_main_text', true);
}

2 Answers
2

The new block editor uses the REST API and by modifying the rest response through the rest_prepare_post filter you compromise the expected data set. I suspect that’s the case here, since you’re modifying all the responses for the post post type, without any conditional restrictions.

Consider creating your own custom route where you can modify the response to your needs without affecting the core/plugin/app use of the builtin REST API routes. You could also consider e.g. the _embed query parameter to get extra information about the category and the featured image.

Leave a Comment