diff --git a/editor/effects.js b/editor/effects.js index 5ad1e102b455a..59e680eaed960 100644 --- a/editor/effects.js +++ b/editor/effects.js @@ -15,7 +15,12 @@ import { __ } from 'i18n'; */ import { getGutenbergURL, getWPAdminURL } from './utils/url'; import { focusBlock, replaceBlocks } from './actions'; -import { getCurrentPost, getCurrentPostId, getBlocks, getPostEdits } from './selectors'; +import { + getCurrentPostId, + getCurrentPostType, + getBlocks, + getPostEdits, +} from './selectors'; export default { REQUEST_POST_UPDATE( action, store ) { @@ -43,7 +48,7 @@ export default { edits: toSend, optimist: { id: transactionId }, } ); - const Model = wp.api.getPostTypeModel( getCurrentPost( state ).type ); + const Model = wp.api.getPostTypeModel( getCurrentPostType( state ) ); new Model( toSend ).save().done( ( newPost ) => { dispatch( { type: 'REQUEST_POST_UPDATE_SUCCESS', @@ -78,9 +83,9 @@ export default { window.history.replaceState( {}, 'Post ' + post.id, newURL ); }, TRASH_POST( action, store ) { - const { dispatch } = store; + const { dispatch, getState } = store; const { postId } = action; - const Model = wp.api.getPostTypeModel( getCurrentPost( store.getState() ).type ); + const Model = wp.api.getPostTypeModel( getCurrentPostType( getState() ) ); new Model( { id: postId } ).destroy().done( () => { dispatch( { ...action, diff --git a/editor/index.js b/editor/index.js index 0186e9c574dd4..9d75de3991580 100644 --- a/editor/index.js +++ b/editor/index.js @@ -41,21 +41,20 @@ if ( settings.timezone.string ) { * Initializes Redux state with bootstrapped post, if provided. * * @param {Redux.Store} store Redux store instance - * @param {?Object} post Bootstrapped post object + * @param {Object} post Bootstrapped post object */ function preparePostState( store, post ) { - if ( ! post ) { - return; - } - store.dispatch( { type: 'RESET_POST', post, } ); - store.dispatch( { - type: 'RESET_BLOCKS', - blocks: parse( post.content.raw ), - } ); + + if ( post.content ) { + store.dispatch( { + type: 'RESET_BLOCKS', + blocks: parse( post.content.raw ), + } ); + } if ( ! post.id ) { // Each property that is set in `post-content.js` (other than `content` @@ -65,8 +64,8 @@ function preparePostState( store, post ) { store.dispatch( { type: 'SETUP_NEW_POST', edits: { - title: post.title.raw, - ...omit( post, 'title', 'content' ), + title: post.title ? post.title.raw : undefined, + ...omit( post, 'title', 'content', 'type' ), }, } ); } @@ -76,7 +75,7 @@ function preparePostState( store, post ) { * Initializes and returns an instance of Editor. * * @param {String} id Unique identifier for editor instance - * @param {Object} post API entity for post to edit + * @param {Object} post API entity for post to edit (type required) */ export function createEditorInstance( id, post ) { const store = createReduxStore(); diff --git a/editor/selectors.js b/editor/selectors.js index 7fe2ece8c7e45..b0e8df92fff67 100644 --- a/editor/selectors.js +++ b/editor/selectors.js @@ -85,6 +85,16 @@ export function getCurrentPost( state ) { return state.currentPost; } +/** + * Returns the post type of the post currently being edited + * + * @param {Object} state Global application state + * @return {String} Post type + */ +export function getCurrentPostType( state ) { + return state.currentPost.type; +} + /** * Returns the ID of the post currently being edited, or null if the post has * not yet been saved. diff --git a/editor/sidebar/last-revision/index.js b/editor/sidebar/last-revision/index.js index 5e74b66446f3b..36540b7df79d1 100644 --- a/editor/sidebar/last-revision/index.js +++ b/editor/sidebar/last-revision/index.js @@ -15,7 +15,7 @@ import PanelBody from 'components/panel/body'; * Internal dependencies */ import './style.scss'; -import { getCurrentPost, isSavingPost } from '../../selectors'; +import { getCurrentPostId, getCurrentPostType, isSavingPost } from '../../selectors'; import { getWPAdminURL } from '../../utils/url'; class LastRevision extends Component { @@ -112,8 +112,8 @@ class LastRevision extends Component { export default connect( ( state ) => { return { - postId: getCurrentPost( state ).id, - postType: getCurrentPost( state ).type, + postId: getCurrentPostId( state ), + postType: getCurrentPostType( state ), isSaving: isSavingPost( state ), }; } diff --git a/editor/sidebar/post-trash/index.js b/editor/sidebar/post-trash/index.js index c737e9bf6bf1e..938c9ea35b3df 100644 --- a/editor/sidebar/post-trash/index.js +++ b/editor/sidebar/post-trash/index.js @@ -13,7 +13,7 @@ import { Button, Dashicon } from 'components'; * Internal dependencies */ import './style.scss'; -import { getCurrentPost } from '../../selectors'; +import { getCurrentPostId, getCurrentPostType } from '../../selectors'; import { trashPost } from '../../actions'; function PostTrash( { postId, postType, ...props } ) { @@ -33,10 +33,9 @@ function PostTrash( { postId, postType, ...props } ) { export default connect( ( state ) => { - const post = getCurrentPost( state ); return { - postId: post.id, - postType: post.type, + postId: getCurrentPostId( state ), + postType: getCurrentPostType( state ), }; }, { trashPost } diff --git a/editor/test/selectors.js b/editor/test/selectors.js index 42bc6f11cde66..16cddf0029233 100644 --- a/editor/test/selectors.js +++ b/editor/test/selectors.js @@ -16,6 +16,7 @@ import { isEditedPostDirty, getCurrentPost, getCurrentPostId, + getCurrentPostType, getPostEdits, getEditedPostTitle, getEditedPostExcerpt, @@ -207,6 +208,18 @@ describe( 'selectors', () => { } ); } ); + describe( 'getCurrentPostType', () => { + it( 'should return the post type', () => { + const state = { + currentPost: { + type: 'post', + }, + }; + + expect( getCurrentPostType( state ) ).to.equal( 'post' ); + } ); + } ); + describe( 'getPostEdits', () => { it( 'should return the post edits', () => { const state = { diff --git a/lib/client-assets.php b/lib/client-assets.php index 932618b622961..1a1ca89fc4032 100644 --- a/lib/client-assets.php +++ b/lib/client-assets.php @@ -413,7 +413,15 @@ function gutenberg_scripts_and_styles( $hook ) { file_get_contents( gutenberg_dir_path() . 'post-content.js' ) ); } else { - // TODO: Error handling. + // ...with a new empty post + // TODO: Error handling if we tried and failed to get a post above + $empty_post = array( + 'type' => 'post', + ); + wp_add_inline_script( + 'wp-editor', + 'window._wpGutenbergPost = ' . wp_json_encode( $empty_post ) . ';' + ); } // Prepare Jed locale data. diff --git a/post-content.js b/post-content.js index 4ebdc7b58c5c0..3f4b930161869 100644 --- a/post-content.js +++ b/post-content.js @@ -2,6 +2,7 @@ * Temporary test post content */ window._wpGutenbergPost = { + type: 'post', title: { raw: 'Welcome to the Gutenberg Editor', },