Unset data from WordPress API (wp-json)

I can already unset (remove specifics from normal posts) in the json returned from the WordPress API. I actually use the following below from this example: https://css-tricks.com/using-the-wp-api-to-fetch-posts/

What I am having trouble with and can’t figure out, is how to change this so it unsets data from a Custom Post Type

Read More

Thoughts?

function qod_remove_extra_data( $data, $post, $context ) {
  // We only want to modify the 'view' context, for reading posts
  if ( $context !== 'view' || is_wp_error( $data ) ) {
    return $data;
  }

  // Here, we unset any data we don't want to see on the front end:
  unset( $data['author'] );
  unset( $data['status'] );
  unset( $data['featured_image'] );
  //etc etc

  return $data;
}

add_filter( 'json_prepare_post', 'qod_remove_extra_data', 12, 3 );

custom post type example filter:

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

  if ( $context !== 'view' || is_wp_error( $data ) ) {
    return $data;
  }

  // Here, we unset any data we don't want to see on the front end:
  unset( $data['author'] );



  return $data;
}

add_filter( 'json_prepare_project', 'projectPost_remove_extra_data', 12, 3 );

Related posts

3 comments

  1. For wp-api v1.x, you need to extend WP_JSON_CustomPostType. There is an example in the pages file (class-wp-json-pages.php)

    <?php
    /**
     * Page post type handlers
     *
     * @package WordPress
     * @subpackage JSON API
     */
    
    /**
     * Page post type handlers
     *
     * This class serves as a small addition on top of the basic post handlers to
     * add small functionality on top of the existing API.
     *
     * In addition, this class serves as a sample implementation of building on top
     * of the existing APIs for custom post types.
     *
     * @package WordPress
     * @subpackage JSON API
     */
    class WP_JSON_Pages extends WP_JSON_CustomPostType {
        /**
         * Base route
         *
         * @var string
         */
        protected $base = '/pages';
    
        /**
         * Post type
         *
         * @var string
         */
        protected $type = 'page';
    
        /**
         * Register the page-related routes
         *
         * @param array $routes Existing routes
         * @return array Modified routes
         */
        public function register_routes( $routes ) {
            $routes = parent::register_routes( $routes );
            $routes = parent::register_revision_routes( $routes );
            $routes = parent::register_comment_routes( $routes );
    
            // Add post-by-path routes
            $routes[ $this->base . '/(?P<path>.+)'] = array(
                array( array( $this, 'get_post_by_path' ),    WP_JSON_Server::READABLE ),
                array( array( $this, 'edit_post_by_path' ),   WP_JSON_Server::EDITABLE | WP_JSON_Server::ACCEPT_JSON ),
                array( array( $this, 'delete_post_by_path' ), WP_JSON_Server::DELETABLE ),
            );
    
            return $routes;
        }
    
        /**
         * Retrieve a page by path name
         *
         * @param string $path
         * @param string $context
         *
         * @return array|WP_Error
         */
        public function get_post_by_path( $path, $context = 'view' ) {
            $post = get_page_by_path( $path, ARRAY_A );
    
            if ( empty( $post ) ) {
                return new WP_Error( 'json_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
            }
    
            return $this->get_post( $post['ID'], $context );
        }
    
        /**
         * Edit a page by path name
         *
         * @param $path
         * @param $data
         * @param array $_headers
         *
         * @return true|WP_Error
         */
        public function edit_post_by_path( $path, $data, $_headers = array() ) {
            $post = get_page_by_path( $path, ARRAY_A );
    
            if ( empty( $post ) ) {
                return new WP_Error( 'json_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
            }
    
            return $this->edit_post( $post['ID'], $data, $_headers );
        }
    
        /**
         * Delete a page by path name
         *
         * @param $path
         * @param bool $force
         *
         * @return true|WP_Error
         */
        public function delete_post_by_path( $path, $force = false ) {
            $post = get_page_by_path( $path, ARRAY_A );
    
            if ( empty( $post ) ) {
                return new WP_Error( 'json_post_invalid_id', __( 'Invalid post ID.' ), array( 'status' => 404 ) );
            }
    
            return $this->delete_post( $post['ID'], $force );
        }
    
        /**
         * Prepare post data
         *
         * @param array $post The unprepared post data
         * @param string $context The context for the prepared post. (view|view-revision|edit|embed|single-parent)
         * @return array The prepared post data
         */
        protected function prepare_post( $post, $context = 'view' ) {
            $_post = parent::prepare_post( $post, $context );
    
            // Override entity meta keys with the correct links
            $_post['meta']['links']['self'] = json_url( $this->base . '/' . get_page_uri( $post['ID'] ) );
    
            if ( ! empty( $post['post_parent'] ) ) {
                $_post['meta']['links']['up'] = json_url( $this->base . '/' . get_page_uri( (int) $post['post_parent'] ) );
            }
    
            return apply_filters( 'json_prepare_page', $_post, $post, $context );
        }
    }
    

    Replace “Pages” with “MyCustomPostTypes” and page with “mycustomposttype”. Just be careful not to rename internal WordPress code that also uses the term page

    Note: probably best to add this as a plugin rather than change the JSON-WP-API plugin

    /**
     * Plugin Name: MyCustom JSON App API
     * Description: MyCustomPost handler for the JSON API
     * Dependency:  This plugin requires JSON-WP-API Plugin!!!! 
     * Author: 
     * Author URI: 
     * Version: 
     * Plugin URI: 
     */
    
  2. If possible, only the examples shown in internet is:

    function qod_remove_extra_data ($ data, $ post, $ context) {
        // We only want to modify the 'view' context, for reading posts 
        if ($ context! == 'view' || is_wp_error ($ data)) {
            return $ data; 
        } 
        // Here, we unset any data we do not want to see on the front end: 
        unset ($data ['author']); 
        unset ($data ['status']); 
        // Continue unsetting whatever other fields you want return $ data;
    }
    add_filter ('json_prepare_post' 'qod remove extra_data', 12, 3);
    

    and right is:

    qod_remove_extra_data function ($ data, $ post, $ context) {
        // We only want to modify the 'view' context, for reading posts 
        if ($ context! == 'view' || is_wp_error ($ data)) {
             unset ( $data->data ['excerpt']); //Example
             unset ($data->data ['content']); //Example
             unset ($data->data ['name field to remove']) 
             //or 
             unset ($data->data ['name field to remove'] ['name subfield if you only want to delete the sub-field of field' ]) 
             return $data; 
         }
    }
    add_filter ('rest_prepare_post' 'qod_remove_extra_data', 12, 3);
    

    IMPORTANT:
    Is:
    add_filter (‘rest_prepare_post‘ ‘qod_remove_extra_data’, 12, 3);

    Not:
    add_filter (‘json_prepare_post‘ ‘qod remove extra_data’, 12, 3); //WRONG

    If is Custom Post Type:
    add_filter (‘rest_prepare_{$post_type}‘ ‘qod_remove_extra_data’, 12, 3);

    EXAMPLE: Name post type = product;
    add_filter (‘rest_prepare_product‘ ‘qod_remove_extra_data’, 12, 3);

    With this code can remove the fields that you want the JSON. By using rest_prepare} _ {$ post_type decide that you eliminated every post_type fields, thus only affected the post_type you want and not all.

  3. It should be no different to remove data from custom post types than from the built-in post types. Have you confirmed that your API call is actually returning your CPTs? First, you should look at the value of what is returned from: http://yourwebsite.com/wp-json/posts/types. Assuming that your CPT type shows up there, you should be able to query for items of that type, e.g. product, by calling: http://yourwebsite.com/wp-json/posts?type=product.

    In other words, you should not change the name of the filter: you still want to tie into json_prepare_post. If you want to make your filter sensitive to post type and only remove certain fields if you have a CPT you could do something like:

    function my_remove_extra_product_data( $data, $post, $context ) {
        // make sure you've got the right custom post type
        if ( 'product' !== $data[ 'type' ] ) {
            return $data;
        }
        // now proceed as you saw in the other examples
        if ( $context !== 'view' || is_wp_error( $data ) ) {
            return $data;
        }
        // unset unwanted fields
        unset( $data[ 'author' ] );
    
        // finally, return the filtered data
        return $data;
    }
    
    // make sure you use the SAME filter hook as for regular posts
    add_filter( 'json_prepare_post', 'my_remove_extra_product_data', 12, 3 );
    

    You can find more documentation in the WP API Getting Started Guide.

Comments are closed.