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

Filter the Post Format list to only formats that are supported #6301

Merged
merged 10 commits into from
Apr 25, 2018
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 receiveThemeSupportsFromIndex( index ) {
return {
type: 'RECEIVE_THEME_SUPPORTS',
themeSupports: index.theme_supports,
};
}
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 theme supports data.
*
* @param {Object} state Current state.
* @param {Object} action Dispatched action.
*
* @return {Object} Updated state.
*/
export function themeSupports( state = {}, action ) {
switch ( action.type ) {
case 'RECEIVE_THEME_SUPPORTS':
return {
...state,
...action.themeSupports,
};
}

return state;
}

export default combineReducers( {
terms,
media,
postTypes,
themeSupports,
} );
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,
receiveThemeSupportsFromIndex,
} 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() {
Copy link
Member

Choose a reason for hiding this comment

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

Elsewhere we seem to be anticipating that index data may be broadly useful, rather than tracking only theme supports. But it's not consistent with how we've implemented resolvers and selectors, as there's only exposed access to theme supports. Scaling this out to other properties will require (maybe not so obviously) refactoring of the resolver to implement an isFulfilled for all index-sourced values (see #6084).

Which is to say: We should probably be consistent one way or the other: Only track theme supports, or implement resolvers and selectors as broadly index-sourced.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's better to focus specifically on theme supports data: 1c6e693

const index = await apiRequest( { path: '/' } );
yield receiveThemeSupportsFromIndex( 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 {*} Index data.
*/
export function getThemeSupports( state ) {
return state.themeSupports;
}
17 changes: 12 additions & 5 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 } from 'lodash';
import { find, get, includes, union } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -30,9 +30,10 @@ const POST_FORMATS = [
{ id: 'chat', caption: __( 'Chat' ) },
];

function PostFormat( { onUpdatePostFormat, postFormat = 'standard', suggestedFormat, instanceId } ) {
function PostFormat( { onUpdatePostFormat, postFormat = 'standard', supportedFormats, suggestedFormat, instanceId } ) {
const postFormatSelectorId = 'post-format-selector-' + instanceId;
const suggestion = find( POST_FORMATS, ( format ) => format.id === suggestedFormat );
const formats = POST_FORMATS.filter( ( format ) => includes( supportedFormats, format.id ) );
const suggestion = find( formats, ( format ) => format.id === suggestedFormat );

// Disable reason: We need to change the value immiediately to show/hide the suggestion if needed

Expand All @@ -47,7 +48,7 @@ function PostFormat( { onUpdatePostFormat, postFormat = 'standard', suggestedFor
onChange={ ( event ) => onUpdatePostFormat( event.target.value ) }
id={ postFormatSelectorId }
>
{ POST_FORMATS.map( ( format ) => (
{ formats.map( ( format ) => (
<option key={ format.id } value={ format.id }>{ format.caption }</option>
) ) }
</select>
Expand All @@ -70,8 +71,14 @@ function PostFormat( { onUpdatePostFormat, postFormat = 'standard', suggestedFor
export default compose( [
withSelect( ( select ) => {
const { getEditedPostAttribute, getSuggestedPostFormat } = select( 'core/editor' );
const postFormat = 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( [ postFormat ], get( themeSupports, 'formats', [] ) );
return {
postFormat: getEditedPostAttribute( 'format' ),
postFormat,
supportedFormats,
suggestedFormat: getSuggestedPostFormat(),
};
} ),
Expand Down
32 changes: 29 additions & 3 deletions lib/compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,30 @@ function gutenberg_add_rest_nonce_to_heartbeat_response_headers( $response ) {

add_filter( 'wp_refresh_nonces', 'gutenberg_add_rest_nonce_to_heartbeat_response_headers' );

/**
* 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 @@ -469,11 +493,12 @@ function gutenberg_get_post_type_viewable( $post_type ) {
}

/**
* Adds the 'viewable' attribute to the REST API response of a post type.
* Adds extra fields to the REST API post type response.
*
* @see https://core.trac.wordpress.org/ticket/43739
* @see https://core.trac.wordpress.org/ticket/43817
*/
function gutenberg_register_rest_api_post_type_viewable() {
function gutenberg_register_rest_api_post_type_fields() {
register_rest_field( 'type',
'viewable',
array(
Expand All @@ -486,5 +511,6 @@ function gutenberg_register_rest_api_post_type_viewable() {
),
)
);

}
add_action( 'rest_api_init', 'gutenberg_register_rest_api_post_type_viewable' );
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'] ) );
}
}