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

Introduce theme_supports with formats to REST API index #6318

Merged
merged 6 commits into from
Apr 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core-data/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,17 @@ export function receivePostTypes( postTypes ) {
postTypes: castArray( postTypes ),
};
}

/**
* Returns an action object used in signalling that the index has been received.
*
* @param {Object} index Index received.
*
* @return {Object} Action object.
*/
export function receiveIndex( index ) {
return {
type: 'RECEIVE_INDEX',
index: index,
};
}
21 changes: 21 additions & 0 deletions core-data/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,29 @@ export function postTypes( state = {}, action ) {
return state;
}

/**
* Reducer managing indexes data.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function indexData( state = {}, action ) {
switch ( action.type ) {
case 'RECEIVE_INDEX':
return {
...state,
...action.index,
};
}

return state;
}

export default combineReducers( {
terms,
media,
postTypes,
indexData,
Copy link
Member

Choose a reason for hiding this comment

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

Is Data suffix adding any value here? Would we want to call other reducers termsData, mediaData as well for consistency's sake?

Copy link
Member Author

Choose a reason for hiding this comment

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

Is Data suffix adding any value here?

For me personally, it denotes that it's the data part of the index. index was too nebulous in my opinion (in comparison to terms, which more clearly communicates itself).

Would we want to call other reducers termsData, mediaData as well for consistency's sake?

I don't think so. However, if you're not a fan of indexData, I'm open to renaming it. Alternatively, we could only put themeSupports in the store, instead of the entire index.

} );
9 changes: 9 additions & 0 deletions core-data/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
receiveTerms,
receiveMedia,
receivePostTypes,
receiveIndex,
} from './actions';

/**
Expand Down Expand Up @@ -44,3 +45,11 @@ export async function* getPostType( state, slug ) {
const postType = await apiRequest( { path: `/wp/v2/types/${ slug }?context=edit` } );
yield receivePostTypes( postType );
}

/**
* Requests theme supports data from the index.
*/
export async function* getThemeSupports() {
const index = await apiRequest( { path: '/' } );
yield receiveIndex( index );
}
11 changes: 11 additions & 0 deletions core-data/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,14 @@ export function getMedia( state, id ) {
export function getPostType( state, slug ) {
return state.postTypes[ slug ];
}

/**
* Return theme suports data in the index.
*
* @param {Object} state Data state.
*
* @return {Mixed?} Index data.
*/
export function getThemeSupports( state ) {
return state.indexData.theme_supports;
}
11 changes: 7 additions & 4 deletions editor/components/post-format/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { find, get } from 'lodash';
import { find, get, union } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -71,11 +71,14 @@ function PostFormat( { onUpdatePostFormat, postFormat = 'standard', supportedFor
export default compose( [
withSelect( ( select ) => {
const { getEditedPostAttribute, getSuggestedPostFormat } = select( 'core/editor' );
const { getPostType } = select( 'core' );
const postType = getPostType( getEditedPostAttribute( 'type' ) );
const format = getEditedPostAttribute( 'format' );
const themeSupports = select( 'core' ).getThemeSupports();
// Ensure current format is always in the set.
// The current format may not be a format supported by the theme.
const supportedFormats = union( [ format ], get( themeSupports, 'formats', [] ) );
return {
postFormat: getEditedPostAttribute( 'format' ),
supportedFormats: get( postType, [ 'formats' ], [] ),
supportedFormats,
suggestedFormat: getSuggestedPostFormat(),
};
} ),
Expand Down
56 changes: 24 additions & 32 deletions lib/compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ function gutenberg_ensure_wp_json_has_permalink_structure( $response ) {
}
add_filter( 'rest_index', 'gutenberg_ensure_wp_json_has_permalink_structure' );

/**
* Ensure that the wp-json index contains the 'theme-supports' setting as
* part of its site info elements.
*
* @param WP_REST_Response $response WP REST API response of the wp-json index.
* @return WP_REST_Response Response that contains theme-supports.
*/
function gutenberg_ensure_wp_json_has_theme_supports( $response ) {
$site_info = $response->get_data();
if ( ! array_key_exists( 'theme_supports', $site_info ) ) {
$site_info['theme_supports'] = array();
}
if ( ! array_key_exists( 'formats', $site_info['theme_supports'] ) ) {
$formats = get_theme_support( 'post-formats' );
$formats = is_array( $formats ) ? array_values( $formats[0] ) : array();
$formats = array_merge( array( 'standard' ), $formats );

$site_info['theme_supports']['formats'] = $formats;
}
$response->set_data( $site_info );
return $response;
}
add_filter( 'rest_index', 'gutenberg_ensure_wp_json_has_theme_supports' );

/**
* As a substitute for the default content `wpautop` filter, applies autop
* behavior only for posts where content does not contain blocks.
Expand Down Expand Up @@ -490,26 +514,6 @@ function gutenberg_get_post_type_viewable( $post_type ) {
return is_post_type_viewable( $post_type['slug'] );
}

/**
* Includes the value for the 'formats' attribute of a post type resource.
*
* @see https://core.trac.wordpress.org/ticket/43817
*
* @param object $post_type Post type response object.
* @return array The list of post formats that the post type supports.
*/
function gutenberg_get_post_type_formats( $post_type ) {
if ( ! post_type_supports( $post_type['slug'], 'post-formats' ) ) {
return array();
}

$formats = get_theme_support( 'post-formats' );
$formats = is_array( $formats ) ? array_values( $formats[0] ) : array();
$formats = array_merge( array( 'standard' ), $formats );

return $formats;
}

/**
* Adds extra fields to the REST API post type response.
*
Expand All @@ -530,17 +534,5 @@ function gutenberg_register_rest_api_post_type_fields() {
)
);

register_rest_field( 'type',
'formats',
array(
'get_callback' => 'gutenberg_get_post_type_formats',
'schema' => array(
'description' => __( 'The list of post formats that this post type supports', 'gutenberg' ),
'type' => 'array',
'context' => array( 'edit', 'view' ),
'readonly' => true,
),
)
);
}
add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_type_fields' );
12 changes: 12 additions & 0 deletions phpunit/class-gutenberg-rest-api-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,16 @@ function test_viewable_field_without_context() {
$result = $response->get_data();
$this->assertFalse( isset( $result['viewable'] ) );
}

/**
* Should include relevant data in the 'theme_supports' key of index.
*/
function test_theme_supports_index() {
$request = new WP_REST_Request( 'GET', '/' );
$response = rest_do_request( $request );
$result = $response->get_data();
$this->assertTrue( isset( $result['theme_supports'] ) );
$this->assertTrue( isset( $result['theme_supports']['formats'] ) );
$this->assertTrue( in_array( 'standard', $result['theme_supports']['formats'] ) );
Copy link
Member

Choose a reason for hiding this comment

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

It'd be good to test that post formats that aren't specified by the theme are not in the results, too.

Copy link
Member Author

Choose a reason for hiding this comment

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

Given post formats can vary from theme to theme, and the theme active in the test suite is uncertain, can you suggest what you'd like me to test?

Copy link
Member

Choose a reason for hiding this comment

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

On second thoughts, I don't know that it needs testing. I'd been looking at WPCOM's API, which tries to avoid loading the theme code if it can, so was considering how to test for that. But, that's not really an issue for Core.

}
}