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 Custom Fields and Advanced Panels to Options modal #10676

Merged
merged 11 commits into from Oct 18, 2018
62 changes: 42 additions & 20 deletions docs/data/data-core-edit-post.md
Expand Up @@ -195,6 +195,19 @@ Returns an array of active meta box locations.

Active meta box locations.

### isMetaBoxLocationVisible

Returns true if a metabox location is active and visible

*Parameters*

* state: Post editor state.
* location: Meta box location to test.

*Returns*

Whether the meta box location is active and visible.

### isMetaBoxLocationActive

Returns true if there is an active meta box in the given location, or false
Expand All @@ -209,6 +222,31 @@ otherwise.

Whether the meta box location is active.

### getMetaBoxesPerLocation

Returns the list of all the available meta boxes for a given location.

*Parameters*

* state: Global application state.
* location: Meta box location to test.

*Returns*

List of meta boxes.

### getAllMetaBoxes

Returns the list of all the available meta boxes.

*Parameters*

* state: Global application state.

*Returns*

List of meta boxes.

### getMetaBox

Returns the state of legacy meta boxes.
Expand Down Expand Up @@ -326,30 +364,14 @@ Returns an action object used to toggle a plugin name flag.

* pluginName: Plugin name.

### initializeMetaBoxState

Returns an action object used to check the state of meta boxes at a location.

This should only be fired once to initialize meta box state. If a meta box
area is empty, this will set the store state to indicate that React should
not render the meta box area.

Example: metaBoxes = { side: true, normal: false }.

This indicates that the sidebar has a meta box but the normal area does not.

*Parameters*

* metaBoxes: Whether meta box locations are active.

### setActiveMetaBoxLocations
### setAvailableMetaBoxesPerLocation

Returns an action object used in signaling that the active meta box
locations have changed.
Returns an action object used in signaling
what Meta boxes are available in which location.

*Parameters*

* locations: New active meta box locations.
* metaBoxesPerLocation: Meta boxes per location.

### requestMetaBoxUpdates

Expand Down
3 changes: 2 additions & 1 deletion docs/reference/deprecated.md
Expand Up @@ -10,7 +10,8 @@ Gutenberg's deprecation policy is intended to support backwards-compatibility fo
- Writing resolvers as async generators has been removed. Use the controls plugin instead.
- `wp.components.AccessibleSVG` component has been removed. Please use `wp.components.SVG` instead.
- The `wp.editor.UnsavedChangesWarning` component no longer accepts a `forceIsDirty` prop.
- `initializeMetaBoxState` action (`core/edit-post`) has been removed. Use `setActiveMetaBoxLocations` action (`core/edit-post`) instead.
- `setActiveMetaBoxLocations` action (`core/edit-post`) has been removed.
- `initializeMetaBoxState` action (`core/edit-post`) has been removed.
- `wp.editPost.initializeEditor` no longer returns an object. Use the `setActiveMetaBoxLocations` action (`core/edit-post`) in place of the existing object's `initializeMetaBoxes` function.
- `setMetaBoxSavedData` action (`core/edit-post`) has been removed.
- `getMetaBoxes` selector (`core/edit-post`) has been removed. Use `getActiveMetaBoxLocations` selector (`core/edit-post`) instead.
Expand Down
32 changes: 22 additions & 10 deletions lib/meta-box-partial-page.php
Expand Up @@ -112,8 +112,8 @@ function gutenberg_filter_meta_boxes( $meta_boxes ) {
$core_normal_meta_boxes = array(
'revisionsdiv',
'postexcerpt',
'trackbacksdiv',
'postcustom',
'trackbacksdiv',
'commentstatusdiv',
'commentsdiv',
'slugdiv',
Expand Down Expand Up @@ -289,9 +289,9 @@ function the_gutenberg_metaboxes() {
*
* @param array $wp_meta_boxes Global meta box state.
*/
$wp_meta_boxes = apply_filters( 'filter_gutenberg_meta_boxes', $wp_meta_boxes );
$locations = array( 'side', 'normal', 'advanced' );
$active_meta_box_locations = array();
$wp_meta_boxes = apply_filters( 'filter_gutenberg_meta_boxes', $wp_meta_boxes );
$locations = array( 'side', 'normal', 'advanced' );
$priorities = array( 'high', 'sorted', 'core', 'default', 'low' );
// Render meta boxes.
?>
<form class="metabox-base-form">
Expand All @@ -302,22 +302,34 @@ function the_gutenberg_metaboxes() {
<div id="poststuff" class="sidebar-open">
<div id="postbox-container-2" class="postbox-container">
<?php
$number_of_meta_boxes = do_meta_boxes(
do_meta_boxes(
$current_screen,
$location,
$post
);

if ( $number_of_meta_boxes > 0 ) {
$active_meta_box_locations[] = $location;
}
?>
</div>
</div>
</form>
<?php endforeach; ?>
<?php

$meta_boxes_per_location = array();
foreach ( $locations as $location ) {
$meta_boxes_per_location[ $location ] = array();
foreach ( $priorities as $priority ) {
$meta_boxes = (array) $wp_meta_boxes[ $current_screen->id ][ $location ][ $priority ];
foreach ( $meta_boxes as $meta_box ) {
if ( ! empty( $meta_box['title'] ) ) {
$meta_boxes_per_location[ $location ][] = array(
'id' => $meta_box['id'],
'title' => $meta_box['title'],
);
}
}
}
}

/**
* Sadly we probably can not add this data directly into editor settings.
*
Expand All @@ -327,7 +339,7 @@ function the_gutenberg_metaboxes() {
* this, and try to get this data to load directly into the editor settings.
*/
$script = 'window._wpLoadGutenbergEditor.then( function() {
wp.data.dispatch( \'core/edit-post\' ).setActiveMetaBoxLocations( ' . wp_json_encode( $active_meta_box_locations ) . ' );
wp.data.dispatch( \'core/edit-post\' ).setAvailableMetaBoxesPerLocation( ' . wp_json_encode( $meta_boxes_per_location ) . ' );
} );';

wp_add_inline_script( 'wp-edit-post', $script );
Expand Down
29 changes: 20 additions & 9 deletions packages/edit-post/src/components/meta-boxes/index.js
@@ -1,25 +1,36 @@
/**
* External dependencies
*/
import { map } from 'lodash';

/**
* WordPress dependencies
*/
import { withSelect } from '@wordpress/data';
import { Fragment } from '@wordpress/element';

/**
* Internal dependencies
*/
import MetaBoxesArea from './meta-boxes-area';
import MetaBoxVisibility from './meta-box-visibility';

function MetaBoxes( { location, isActive } ) {
if ( ! isActive ) {
return null;
}

return <MetaBoxesArea location={ location } />;
function MetaBoxes( { location, isVisible, metaBoxes } ) {
return (
<Fragment>
{ map( metaBoxes, ( { id } ) => (
<MetaBoxVisibility id={ id } />
Copy link
Member

Choose a reason for hiding this comment

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

Does this not demand a key?

Edit: Yes, there's a console error.

Copy link
Contributor

Choose a reason for hiding this comment

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

It does, copy/paste :(

) ) }
{ isVisible && <MetaBoxesArea location={ location } /> }
Copy link
Member

Choose a reason for hiding this comment

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

Is it necessary to render this component at all if ! isVisible? i.e. an ifCondition.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's necessary to handle the visibility.

</Fragment>
);
}

export default withSelect( ( select, ownProps ) => {
const { isMetaBoxLocationActive } = select( 'core/edit-post' );
export default withSelect( ( select, { location } ) => {
const { isMetaBoxLocationVisible, getMetaBoxesPerLocation } = select( 'core/edit-post' );

return {
isActive: isMetaBoxLocationActive( ownProps.location ),
metaBoxes: getMetaBoxesPerLocation( location ),
isVisible: isMetaBoxLocationVisible( location ),
};
} )( MetaBoxes );
@@ -0,0 +1,33 @@
/**
* WordPress dependencies
*/
import { Component } from '@wordpress/element';
import { withSelect } from '@wordpress/data';

class MetaBoxVisibility extends Component {
componentDidMount() {
this.updateDOM();
}

componentDidUpdate( prevProps ) {
if ( this.props.isVisible !== prevProps.isVisible ) {
this.updateDOM();
}
}

updateDOM() {
const { id, isVisible } = this.props;
const element = document.getElementById( id );
if ( element ) {
element.style.display = isVisible ? '' : 'none';
}
}

render() {
return null;
}
}

export default withSelect( ( select, { id } ) => ( {
isVisible: select( 'core/edit-post' ).isEditorPanelEnabled( `meta-box-${ id }` ),
} ) )( MetaBoxVisibility );
12 changes: 10 additions & 2 deletions packages/edit-post/src/components/options-modal/index.js
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { get } from 'lodash';
import { get, map } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -20,7 +20,7 @@ import { EnablePublishSidebarOption, EnableTipsOption, EnablePanelOption } from

const MODAL_NAME = 'edit-post/options';

export function OptionsModal( { isModalActive, closeModal } ) {
export function OptionsModal( { isModalActive, closeModal, metaBoxes = [] } ) {
if ( ! isModalActive ) {
return null;
}
Expand Down Expand Up @@ -54,13 +54,21 @@ export function OptionsModal( { isModalActive, closeModal } ) {
<EnablePanelOption label={ __( 'Page Attributes' ) } panelName="page-attributes" />
</PageAttributesCheck>
</Section>
{ metaBoxes.length !== 0 && (
<Section title={ __( 'Advanced Panels' ) }>
{ map( metaBoxes, ( { title, id } ) => (
<EnablePanelOption key={ id } label={ title } panelName={ `meta-box-${ id }` } />
) ) }
</Section>
) }
</Modal>
);
}

export default compose(
withSelect( ( select ) => ( {
isModalActive: select( 'core/edit-post' ).isModalActive( MODAL_NAME ),
metaBoxes: select( 'core/edit-post' ).getAllMetaBoxes(),
} ) ),
withDispatch( ( dispatch ) => {
return {
Expand Down
56 changes: 19 additions & 37 deletions packages/edit-post/src/store/actions.js
@@ -1,8 +1,3 @@
/**
* External dependencies
*/
import { reduce } from 'lodash';

/**
* WordPress dependencies
*/
Expand Down Expand Up @@ -172,51 +167,38 @@ export function togglePinnedPluginItem( pluginName ) {
};
}

/**
* Returns an action object used to check the state of meta boxes at a location.
*
* This should only be fired once to initialize meta box state. If a meta box
* area is empty, this will set the store state to indicate that React should
* not render the meta box area.
*
* Example: metaBoxes = { side: true, normal: false }.
*
* This indicates that the sidebar has a meta box but the normal area does not.
*
* @param {Object} metaBoxes Whether meta box locations are active.
*
* @return {Object} Action object.
*/
export function initializeMetaBoxState( metaBoxes ) {
export function initializeMetaBoxState() {
deprecated( 'initializeMetaBoxState action (`core/edit-post`)', {
alternative: 'setActiveMetaBoxLocations',
plugin: 'Gutenberg',
version: '4.2',
} );
return {
type: 'DO_NOTHING',
};
}

const locations = reduce( metaBoxes, ( result, isActive, location ) => {
if ( isActive ) {
result = result.concat( location );
}

return result;
}, [] );

return setActiveMetaBoxLocations( locations );
export function setActiveMetaBoxLocations() {
deprecated( 'setActiveMetaBoxLocations action (`core/edit-post`)', {
plugin: 'Gutenberg',
version: '4.2',
} );
return {
type: 'DO_NOTHING',
};
}

/**
* Returns an action object used in signaling that the active meta box
* locations have changed.
* Returns an action object used in signaling
* what Meta boxes are available in which location.
*
* @param {string[]} locations New active meta box locations.
* @param {Object} metaBoxesPerLocation Meta boxes per location.
*
* @return {Object} Action object.
*/
export function setActiveMetaBoxLocations( locations ) {
export function setAvailableMetaBoxesPerLocation( metaBoxesPerLocation ) {
return {
type: 'SET_ACTIVE_META_BOX_LOCATIONS',
locations,
type: 'SET_META_BOXES_PER_LOCATIONS',
metaBoxesPerLocation,
};
}

Expand Down