3

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

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 );

new example with custom post type **

function projectPost_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'] );



  return $data;
}

add_filter( 'json_prepare_project', 'projectPost_remove_extra_data', 12, 3 );
9
  • 1
    You need to change json_prepare_post to json_prepare_{$post_type} Sep 10, 2015 at 22:44
  • @czerspalace would you set the specifics for $post_type in the function?
    – RMH
    Sep 10, 2015 at 22:48
  • Yes, or create a new function that is hooked to json_prepare_{$post_type} and add the specifics in that function Sep 10, 2015 at 23:35
  • @czerspalace i updated my example using $post_type, pretty my example is wrong though. Thoughts on fixes?
    – RMH
    Sep 10, 2015 at 23:44
  • Sorry, {$post_type} should be replaced by the name of your custom post type, so if post type is project, then it would be json_prepare_project Sep 10, 2015 at 23:48

2 Answers 2

8

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:

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)) {
         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 (No underscores)

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.

2
  • Fantastic answer, saved me so much time, thank you! The example in the API handbook is far too overcomplicated for a non wordpress/php developer trying to build out a decoupled front end with this API May 8, 2017 at 5:24
  • Good thing it was helpful. Anything here is. ;) May 9, 2017 at 8:11
0

Have a look at the wp-api code for pages (which are custom post types).

You can modify the code, changing pages to whatever your post type is called (just be careful about doing a search and replace for all "pages" as some of them are wordpress function calls or filters)

<?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 );
    }
}

Put your custom code in edit or filter etc, and away you go!

ps - don't forget to turn it into a proper plugin! You can add as a new plugin and manage it better that way using:

<?php
/**
 * Plugin Name: My JSON App API
 * Description: My Route and Endpoint handler for the JSON API
 * Dependency:  This plugin requires JSON BasicKey Authentication Plugin!!!! 
 * Author: Blah Blah Blah, plus much original code from the WordPress API Team
 * Author URI: https://www.example.com
 * Version: 1.2
 * Plugin URI: https://www.example.com
 */

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if (!defined("MY_JSON_API_VERSION")) {
    define ("MY_JSON_API_VERSION",  "1.2") ;
}

function my_json_api_init() {
    global $my_json_api_mobile_users;
    $my_json_api_mobile_users = new my_JSON_API_MobileUsers();
    add_filter( 'json_endpoints', array( $my_json_api_mobile_users, 'register_routes' ) );
}
add_action( 'wp_json_server_before_serve', 'my_json_api_init' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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