0

I am preparing a plugin for REST API integration (the WP 4.7 core version) by providing custom endpoints for data from the plugin. One of the things I am trying to do is to set a _links property in the response and make the linked resource embeddable. Heavily simplified code excerpt:

class Clgs_REST_Logs extends WP_REST_Controller {
    const NSPACE = 'clgs';
    const BASE = 'logs';

    public function register_routes() {
        register_rest_route( self::NSPACE, '/' . self::BASE, array(
            array(
                'methods'   => WP_REST_Server::READABLE,
                'callback'  => array( $this, 'get_items' ),
             ),
            'schema' => array( $this, 'get_public_item_schema' ),
        ) );
        register_rest_route( self::NSPACE, '/' . self::BASE . '/count', array(
            array(
                'methods'   => WP_REST_Server::READABLE,
                'callback'  => array( $this, 'get_count' ),
            ),
            'schema' => array( $this, 'get_count_schema' ),
        ) );
    }

    public function get_items( $request ) {
        $log_entries = // get an array

        $collection = $this->prepare_collection_for_response( $log_entries, $request );
        $response = rest_ensure_response( array(
            'items' => $collection
         ) );

        $max_pages = max( 1, ceil( $total_items / (int) $params['per_page'] ) );

        $this->set_count_headers( $response, (int) $total_items, (int) $max_pages );

        $count_link =  $this->prepare_link_url( array( self::BASE, 'count' ) );
        $response->add_links( array (
            'count'  => array(
                'href' => $count_link,
                'embeddable' => true
            ),
        ) );

        return $response;
    }

    public function get_count( $request ) {
        // provide some statistics data
    }

    public function prepare_link_url ( $parts = array() ) {
        array_unshift( $parts, self::NSPACE );
        return rest_url( implode( '/', $parts ) . '/' );
    }
}

A response to a request http://wptesting.intern/index.php/wp-json/clgs/logs/?_embed looks like this:

{
    "items": [...],
    "_links": {
        "count": [{
            "embeddable": true,
            "href": "http://wptesting.intern/index.php/wp-json/clgs/logs/"
        }]
    },
    "_embedded": {
        "count": [{
            "code": "rest_no_route",
            "message": "No route was found matching the URL and request method",
            "data": {"status":404}
        }]
    }
}

Requests to http://wptesting.intern/index.php/wp-json/clgs/logs/count/, if done separately, succeeds.

I have done this additionally with pretty premalinks disabled and http://wptesting.intern/index.php/?route=... to be sure this is not a routing rewrite issue, and the same thing happens.

Has anyone an idea why the embedding fails?

1 Answer 1

1

The slash at the end is the culprit. While real requests with a / at the end of the route get wp_unslash()ed before resolving, the links for embeds do not.

So,

    public function prepare_link_url ( $parts = array() ) {
        array_unshift( $parts, self::NSPACE );
        return rest_url( implode( '/', $parts ) );
    }

does the trick.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.