diff --git a/editor/store/selectors.js b/editor/store/selectors.js index cc0707801aebd..b26587a2cfb17 100644 --- a/editor/store/selectors.js +++ b/editor/store/selectors.js @@ -24,7 +24,6 @@ import createSelector from 'rememo'; */ import { serialize, getBlockType, getBlockTypes, hasBlockSupport } from '@wordpress/blocks'; import { __ } from '@wordpress/i18n'; -import { addQueryArgs } from '@wordpress/url'; import { moment } from '@wordpress/date'; /*** @@ -354,12 +353,7 @@ export function getEditedPostExcerpt( state ) { * @return {string} Preview URL. */ export function getEditedPostPreviewLink( state ) { - const link = state.currentPost.link; - if ( ! link ) { - return null; - } - - return addQueryArgs( link, { preview: 'true' } ); + return getCurrentPost( state ).preview_link || null; } /** diff --git a/editor/store/test/selectors.js b/editor/store/test/selectors.js index 602672368f41d..5ef418a89affe 100644 --- a/editor/store/test/selectors.js +++ b/editor/store/test/selectors.js @@ -1065,14 +1065,14 @@ describe( 'selectors', () => { expect( getEditedPostPreviewLink( state ) ).toBeNull(); } ); - it( 'should return the correct url adding a preview parameter to the query string', () => { + it( 'should return the correct url when the post object has a preview_link', () => { const state = { currentPost: { - link: 'https://andalouses.com/beach', + preview_link: 'https://andalouses.com/?p=1&preview=true', }, }; - expect( getEditedPostPreviewLink( state ) ).toBe( 'https://andalouses.com/beach?preview=true' ); + expect( getEditedPostPreviewLink( state ) ).toBe( 'https://andalouses.com/?p=1&preview=true' ); } ); } ); diff --git a/lib/rest-api.php b/lib/rest-api.php index bfd2d8b5ac756..c99a15447d93d 100644 --- a/lib/rest-api.php +++ b/lib/rest-api.php @@ -424,6 +424,45 @@ function gutenberg_register_rest_api_post_revisions() { } add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_revisions' ); +/** + * Get the preview link for the post object. + * + * @see https://github.com/WordPress/gutenberg/issues/4555 + * + * @param WP_Post $post Post object. + * @return string + */ +function gutenberg_get_post_preview_link( $post ) { + return get_preview_post_link( $post['id'] ); +} + +/** + * Adds the 'preview_link' attribute to the REST API response of a post. + * + * @see https://github.com/WordPress/gutenberg/issues/4555 + */ +function gutenberg_register_rest_api_post_preview_link() { + foreach ( get_post_types( array( 'show_in_rest' => true ), 'names' ) as $post_type ) { + if ( ! is_post_type_viewable( $post_type ) ) { + continue; + } + register_rest_field( $post_type, + 'preview_link', + array( + 'get_callback' => 'gutenberg_get_post_preview_link', + 'schema' => array( + 'description' => __( 'Preview link for the post.', 'gutenberg' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'edit' ), + 'readonly' => true, + ), + ) + ); + } +} +add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_preview_link' ); + /** * Ensure that the wp-json index contains the 'theme-supports' setting as * part of its site info elements. diff --git a/phpunit/class-gutenberg-rest-api-test.php b/phpunit/class-gutenberg-rest-api-test.php index 5fb617fc6634d..9bdaf81a2bd9b 100644 --- a/phpunit/class-gutenberg-rest-api-test.php +++ b/phpunit/class-gutenberg-rest-api-test.php @@ -445,4 +445,19 @@ public function test_get_pages_unbounded_per_page_unauthorized() { $data = $response->get_data(); $this->assertEquals( 'rest_forbidden_per_page', $data['code'] ); } + + public function test_get_page_edit_context_includes_preview() { + wp_set_current_user( $this->editor ); + $page_id = $this->factory->post->create( array( + 'post_type' => 'page', + 'post_status' => 'draft', + ) ); + $page = get_post( $page_id ); + $request = new WP_REST_Request( 'GET', '/wp/v2/pages/' . $page_id ); + $request->set_param( 'context', 'edit' ); + $response = rest_get_server()->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + $data = $response->get_data(); + $this->assertEquals( get_preview_post_link( $page ), $data['preview_link'] ); + } }