Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for pages and other custom post types #1276

Merged
merged 7 commits into from
Jun 22, 2017
Merged

Conversation

westonruter
Copy link
Member

Fixes #1272.

Will be rebased once #1274 is merged (also if it is not merged).

@westonruter westonruter added the [Status] In Progress Tracking issues with work in progress label Jun 19, 2017
@westonruter westonruter self-assigned this Jun 19, 2017
@aduth
Copy link
Member

aduth commented Jun 19, 2017

What else does this need for a proper review? Trying to decide if we should expedite this instead of #1274. Guessing some client-side work with saving non-posts via the API client?

@westonruter
Copy link
Member Author

@adamsilverstein what suggestions do you have to obtain the Backbone model name given the PHP-discovered $rest_base as seen in this PR?

@adamsilverstein
Copy link
Member

adamsilverstein commented Jun 20, 2017

@westonruter once we have the $rest_base we can localize that directly for the client, then filter the models to find the model that has the matching route.

Something like:

var modelToUse = _.filter( wp.api.models, function( model ) {
	return ( 
		model.prototype.route && 
		0 === model.prototype.route.index.indexOf( restBase )
	 );
} );

@westonruter
Copy link
Member Author

@adamsilverstein here's what I've come up with, but it certainly doesn't feel very elegant:

	// Export REST bases for all post types.
	$post_type_rest_base_mapping = array();
	foreach ( get_post_types( array(), 'objects' ) as $post_type_object ) {
		$rest_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name;
		$post_type_rest_base_mapping[ $post_type_object->name ] = $rest_base;
	}
	$script = sprintf( 'wp.api.postTypeRestBaseMapping = %s;', wp_json_encode( $post_type_rest_base_mapping ) );
	$script .= <<<JS
		wp.api.getPostTypeModel = function( postType ) {
			var route = '/' + wpApiSettings.versionString + this.postTypeRestBaseMapping[ postType ] + '/(?P<id>[\\\\d]+)';
			return _.first( _.filter( wp.api.models, function( model ) {
				return model.prototype.route && route === model.prototype.route.index;
			} ) );
		};
		wp.api.getPostTypeRevisionsCollection = function( postType ) {
			var route = '/' + wpApiSettings.versionString + this.postTypeRestBaseMapping[ postType ] + '/(?P<parent>[\\\\d]+)/revisions';
			return _.first( _.filter( wp.api.collections, function( model ) {
				return model.prototype.route && route === model.prototype.route.index;
			} ) );
		};
JS;
	wp_add_inline_script( 'wp-api', $script );

@westonruter westonruter changed the title [WIP] Add support for pages and other custom post types Add support for pages and other custom post types Jun 20, 2017
@westonruter westonruter removed the [Status] In Progress Tracking issues with work in progress label Jun 20, 2017
@westonruter
Copy link
Member Author

Alright, with 2dbda35 the pages can now be edited and saved with revisions pulled in. It would be ideal if the WP-API Backbone client provided facilities for looking up models and collections based on a post type. The method used here feels very much like a workaround.

The sidebar still says “Post Settings” but I think that it should just be changed to “Settings” for the sake of consistency across types and also for the sake of translatability since “%s Settings” is not among a registered post type's labels.

Once this PR is blessed, I'll close #1274 and rebase this PR to remove the revert commit.

@adamsilverstein
Copy link
Member

@westonruter - I agree we can make this much more succinct by providing a helper function in the client to get the model by route (or what you are calling 'baseMapping' here. something like wp.api.getModelByRoute( route ). I will open a ticket in track and work on adding something for 4.9.

@westonruter
Copy link
Member Author

I didn't include the WP-API extensions in a separate JS file since I wasn't sure where to put them and I wanted confirmation on the approach.

@adamsilverstein
Copy link
Member

I opened a trac ticket to add this enhancement to the client: https://core.trac.wordpress.org/ticket/41111

@aduth
Copy link
Member

aduth commented Jun 21, 2017

The sidebar still says “Post Settings” but I think that it should just be changed to “Settings” for the sake of consistency across types and also for the sake of translatability since “%s Settings” is not among a registered post type's labels.

We should probably create an issue to track this for discussion. Maybe we can keep the "Post Settings" label if we know it to be of the 'post' type, otherwise falling back to a more generic label.

@aduth
Copy link
Member

aduth commented Jun 21, 2017

The inspector "Post" prefix should also probably be determined by the post type:

Post prefix
)

But fine to tackle in a subsequent pull request.

$post_type_rest_base_mapping[ $post_type_object->name ] = $rest_base;
}
$script = sprintf( 'wp.api.postTypeRestBaseMapping = %s;', wp_json_encode( $post_type_rest_base_mapping ) );
$script .= <<<JS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add an inline comment noting that our adding to the wp.api global here is temporary until support is added to the client proper? Maybe a link to the Trac ticket too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering also if we ought to split out some of the unrelated logic here, like bootstrapping wp.api.getPostTypeModel with all post type REST bases, or even below with getting / validating post and post type.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aduth can you explain further on what you mean by splitting out unrelated logic?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just thinking that this function is doing a lot of work, when it should be simple enqueues. Are these overrides specific to the editor? Maybe binding to anywhere wp-api is enqueued. Or at least a separate function / file, or even separate action hook? Similarly below with retrieving and validating post to be edited.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see what you mean. The PHP function is doing a lot of work. 👍

@@ -57,7 +57,8 @@ class LastRevision extends Component {
}
this.setState( { loading: true } );
const postIdToLoad = this.props.postId;
this.fetchRevisionsRequest = new wp.api.collections.PostRevisions( {}, { parent: postIdToLoad } ).fetch()
const Collection = wp.api.getPostTypeRevisionsCollection( this.props.postType || 'post' );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it should be the responsibility of the (or a new) selector to perform the fallback logic, if we expect it to be a common need? i.e. getCurrentPostType = ( state ) => getCurrentPost( state ).type || 'post';

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'll just remove the || 'post' part altogether. If the collection doesn't exist, then it should be due to revisions not being supported, and the component should render nothing.

@westonruter
Copy link
Member Author

Rebased to remove page removal/revert. Former HEAD was 2dbda35.

@aduth
Copy link
Member

aduth commented Jun 21, 2017

Added 6245840 to use getCurrentPost selector in retrieving post type, the thinking being that selectors are a generally useful abstraction to isolate common behaviors (facilitating refactoring, testing, improving readability of intent).

Looks ready to merge if you agree 👍

@mtias mtias added [Type] Task Issues or PRs that have been broken down into an individual action to take Gutenberg Plugin Issues or PRs related to Gutenberg Plugin management related efforts labels Jun 22, 2017
@charamza
Copy link

charamza commented Jul 4, 2017

So there is now ability to use gutenberg for custom post types? I tried it with version 0.3.0 and it replied that "No route was found matching the URL and request method". Should I add some property to that register_post_type function, that will enable gutenberg or it should work without it?

image
(this happens when i click on gutenberg with custom post type)

Also are you planning to add ability that when I click on 'Add custom type post', it will move user straight to gutenberg instead of normal editor for custom type post creation? Or atleast that when there's post_type GET parameter in guteberg, it will add that post into it's custom post type category. Now it just adds it to other basic posts.

Thanks for reply in advance

@westonruter
Copy link
Member Author

@herovis Gutenberg depends on the post type being accessible via the REST API. So yeah, in your register_post_type() call you should make sure that it includes 'show_in_rest' => true.

Also are you planning to add ability that when I click on 'Add custom type post', it will move user straight to gutenberg instead of normal editor for custom type post creation? Or atleast that when there's post_type GET parameter in guteberg, it will add that post into it's custom post type category. Now it just adds it to other basic posts.

In the future, Gutenberg will be the default editor, so yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Gutenberg Plugin Issues or PRs related to Gutenberg Plugin management related efforts [Type] Task Issues or PRs that have been broken down into an individual action to take
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants