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

Block Library: Add EntityProvider, controlled InnerBlocks and basic template blocks. #17135

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2460ea4
Editor: Update the store to use Core Data entities.
aduth Jul 25, 2019
35fde48
Editor: Fix selector test suites.
epiqueras Aug 6, 2019
ebfb4a7
Editor: Fix some legacy selectors and behaviors.
epiqueras Aug 7, 2019
a0d9df9
Editor: Fix action tests.
epiqueras Aug 7, 2019
de0df21
Editor: Fix remaining broken unit tests.
epiqueras Aug 7, 2019
84c4fa9
Editor: Fix more tests.
epiqueras Aug 8, 2019
4fb773f
Editor: Fix more e2e test behaviors.
epiqueras Aug 8, 2019
0299d35
Editor: Fix preview functionality.
epiqueras Aug 8, 2019
75bf989
Core Data: Fix autosaves filtering.
epiqueras Aug 8, 2019
e2684df
Editor: Don't make entity dirty with initial edits.
epiqueras Aug 9, 2019
a2b732a
Editor: Don't save if the post is not saveable.
epiqueras Aug 9, 2019
e8a6b5d
Core Data: Fix merged edits logic.
epiqueras Aug 9, 2019
5c740f5
Core Data: Fix undo to fit e2e expected behaviors.
epiqueras Aug 9, 2019
1c11329
Core Data: Handle more change detection and saving flows.
epiqueras Aug 9, 2019
08a5eab
Block Editor: Fix undo level logic.
epiqueras Aug 9, 2019
614b278
Core Data: Clean up undo reducer comment.
epiqueras Aug 9, 2019
152b76d
Editor: Make `serializeBlocks` a util.
epiqueras Aug 13, 2019
71f242a
Core Data: Clarify raw attribute usage.
epiqueras Aug 15, 2019
ff28c04
Core Data: Memoize .
epiqueras Aug 15, 2019
450b7f2
Core Data: Use new raw entity record selector instead of modifying th…
epiqueras Aug 19, 2019
4c998a2
Core Data: Make save notices the caller's responsibility.
epiqueras Aug 19, 2019
87adf2b
Editor: Use the store key constant in actions instead of a string lit…
epiqueras Aug 19, 2019
1f48897
Editor: Defer serialization of blocks until save.
epiqueras Aug 19, 2019
a2e2487
Editor: Fix raw content access in set up.
epiqueras Aug 20, 2019
f9ae3af
Editor: Revert broken test change.
epiqueras Aug 20, 2019
9334354
Editor: Make initial edits a dirtying operation.
epiqueras Aug 21, 2019
79d0b6a
Editor: Add comment clarifying why we set content to a new function o…
epiqueras Aug 21, 2019
fa5365e
Demo: Fix tests to consider the initial edits dirtying.
epiqueras Aug 21, 2019
4d5de1b
Core Data: Set auto-drafts to drafts when autosaving them.
epiqueras Aug 21, 2019
ff96d9d
Core Data: Add `EntityProvider` and `useEntityProp`.
epiqueras Aug 21, 2019
639e1fd
Blocks: Add "theme" block category.
epiqueras Aug 21, 2019
ca4013b
Block Editor: Support a semi-controlled mode for `InnerBlocks`.
epiqueras Aug 22, 2019
4782e5d
Block Library: Implement Post, Post Title, and Post Content Blocks.
epiqueras Aug 22, 2019
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
22 changes: 4 additions & 18 deletions docs/designers-developers/developers/data/data-core-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ _Related_

<a name="getBlocksForSerialization" href="#getBlocksForSerialization">#</a> **getBlocksForSerialization**

> **Deprecated** since Gutenberg 6.2.0.

Returns a set of blocks which are to be used in consideration of the post's
generated save content.

Expand Down Expand Up @@ -309,8 +311,7 @@ _Returns_

<a name="getEditedPostContent" href="#getEditedPostContent">#</a> **getEditedPostContent**

Returns the content of the post being edited, preferring raw string edit
before falling back to serialization of block state.
Returns the content of the post being edited.

_Parameters_

Expand Down Expand Up @@ -740,6 +741,7 @@ Return true if the current post has already been published.
_Parameters_

- _state_ `Object`: Global application state.
- _currentPost_ `?Object`: Explicit current post for bypassing registry selector.

_Returns_

Expand Down Expand Up @@ -1041,10 +1043,6 @@ _Parameters_

- _edits_ `Object`: Post attributes to edit.

_Returns_

- `Object`: Action object.

<a name="enablePublishSidebar" href="#enablePublishSidebar">#</a> **enablePublishSidebar**

Returns an action object used in signalling that the user has enabled the
Expand Down Expand Up @@ -1178,10 +1176,6 @@ _Related_
Returns an action object used in signalling that undo history should
restore last popped state.

_Returns_

- `Object`: Action object.

<a name="refreshPost" href="#refreshPost">#</a> **refreshPost**

Action generator for handling refreshing the current post.
Expand Down Expand Up @@ -1240,10 +1234,6 @@ _Parameters_
- _blocks_ `Array`: Block Array.
- _options_ `?Object`: Optional options.

_Returns_

- `Object`: Action object

<a name="resetPost" href="#resetPost">#</a> **resetPost**

Returns an action object used in signalling that the latest version of the
Expand Down Expand Up @@ -1357,10 +1347,6 @@ Action generator for trashing the current post in the editor.

Returns an action object used in signalling that undo history should pop.

_Returns_

- `Object`: Action object.

<a name="unlockPostSaving" href="#unlockPostSaving">#</a> **unlockPostSaving**

Returns an action object used to signal that post saving is unlocked.
Expand Down
16 changes: 16 additions & 0 deletions docs/designers-developers/developers/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,22 @@ _Returns_

- `?Object`: The entity record's save error.

<a name="getRawEntityRecord" href="#getRawEntityRecord">#</a> **getRawEntityRecord**

Returns the entity's record object by key,
with its attributes mapped to their raw values.

_Parameters_

- _state_ `Object`: State tree.
- _kind_ `string`: Entity kind.
- _name_ `string`: Entity name.
- _key_ `number`: Record's key.

_Returns_

- `?Object`: Object with the entity's raw attributes.

<a name="getRedoEdit" href="#getRedoEdit">#</a> **getRedoEdit**

Returns the next edit from the current undo offset
Expand Down
20 changes: 20 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,26 @@ function gutenberg_reregister_core_block_types() {
}
add_action( 'init', 'gutenberg_reregister_core_block_types' );

/**
* Adds new block categories needed by the Gutenberg plugin.
*
* @param array $categories List of block categories.
*
* @return array List of block categories with the new categories added.
*/
function gutenberg_filter_block_categories( $categories ) {
return array_merge(
$categories,
array(
array(
'slug' => 'theme',
'title' => __( 'Theme Blocks', 'gutenberg' ),
),
)
);
}
add_filter( 'block_categories', 'gutenberg_filter_block_categories' );

/**
* Registers a new block style.
*
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions packages/block-editor/src/components/block-list/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
replaceBlocks,
toggleSelection,
setNavigationMode,
__unstableMarkLastChangeAsPersistent,
} = dispatch( 'core/block-editor' );

return {
Expand Down Expand Up @@ -744,6 +745,12 @@ const applyWithDispatch = withDispatch( ( dispatch, ownProps, { select } ) => {
}
},
onReplace( blocks, indexToSelect ) {
if (
blocks.length &&
! isUnmodifiedDefaultBlock( blocks[ blocks.length - 1 ] )
) {
__unstableMarkLastChangeAsPersistent();
}
replaceBlocks( [ ownProps.clientId ], blocks, indexToSelect );
},
onShiftSelection() {
Expand Down
26 changes: 24 additions & 2 deletions packages/block-editor/src/components/inner-blocks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class InnerBlocks extends Component {
}

componentDidMount() {
const { innerBlocks } = this.props.block;
const { block, value, replaceInnerBlocks } = this.props;
const { innerBlocks } = block;
// only synchronize innerBlocks with template if innerBlocks are empty or a locking all exists
if ( innerBlocks.length === 0 || this.getTemplateLock() === 'all' ) {
this.synchronizeBlocksWithTemplate();
Expand All @@ -55,10 +56,21 @@ class InnerBlocks extends Component {
templateInProcess: false,
} );
}

// Set controlled blocks value from parent, if any.
if ( value ) {
replaceInnerBlocks( value );
}
}

componentDidUpdate( prevProps ) {
const { template, block } = this.props;
const {
block,
template,
isLastBlockChangePersistent,
onInput,
onChange,
} = this.props;
const { innerBlocks } = block;

this.updateNestedSettings();
Expand All @@ -69,6 +81,14 @@ class InnerBlocks extends Component {
this.synchronizeBlocksWithTemplate();
}
}

// Sync with controlled blocks value from parent, if possible.
if ( prevProps.block.innerBlocks !== innerBlocks ) {
const resetFunc = isLastBlockChangePersistent ? onInput : onChange;
if ( resetFunc ) {
resetFunc( innerBlocks );
}
}
}

/**
Expand Down Expand Up @@ -151,6 +171,7 @@ InnerBlocks = compose( [
getBlockListSettings,
getBlockRootClientId,
getTemplateLock,
isLastBlockChangePersistent,
} = select( 'core/block-editor' );
const { clientId } = ownProps;
const block = getBlock( clientId );
Expand All @@ -161,6 +182,7 @@ InnerBlocks = compose( [
blockListSettings: getBlockListSettings( clientId ),
hasOverlay: block.name !== 'core/template' && ! isBlockSelected( clientId ) && ! hasSelectedInnerBlock( clientId, true ),
parentLock: getTemplateLock( rootClientId ),
isLastBlockChangePersistent: isLastBlockChangePersistent(),
};
} ),
withDispatch( ( dispatch, ownProps ) => {
Expand Down
10 changes: 10 additions & 0 deletions packages/block-library/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ import * as tagCloud from './tag-cloud';

import * as classic from './classic';

// Custom Entity Blocks
import * as post from './post';
import * as postTitle from './post-title';
import * as postContent from './post-content';

/**
* Function to register an individual block.
*
Expand Down Expand Up @@ -138,6 +143,11 @@ export const registerCoreBlocks = () => {
textColumns,
verse,
video,

// Register Custom Entity Blocks.
post,
postTitle,
postContent,
].forEach( registerBlock );

setDefaultBlockName( paragraph.name );
Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/post-content/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "core/post-content",
"category": "theme"
}
25 changes: 25 additions & 0 deletions packages/block-library/src/post-content/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* WordPress dependencies
*/
import { useEntityProp } from '@wordpress/core-data';
import { useMemo, useCallback } from '@wordpress/element';
import { parse } from '@wordpress/blocks';
import { InnerBlocks } from '@wordpress/block-editor';
import { serializeBlocks } from '@wordpress/editor';

export default function PostContentEdit() {
const [ content, setContent ] = useEntityProp( 'post', 'content' );
const initialBlocks = useMemo( () => parse( content ), [] );
const [ blocks = initialBlocks, setBlocks ] = useEntityProp( 'post', 'blocks' );
return (
<InnerBlocks
value={ blocks }
onChange={ setBlocks }
onInput={ useCallback( () => {
setContent( ( { blocks: blocksForSerialization = [] } ) =>
serializeBlocks( blocksForSerialization )
);
}, [] ) }
/>
);
}
11 changes: 11 additions & 0 deletions packages/block-library/src/post-content/icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* WordPress dependencies
*/
import { SVG, Path } from '@wordpress/components';

export default (
<SVG xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24">
<Path fill="none" d="M0 0h24v24H0V0z" />
<Path d="M3 15h18v-2H3v2zm0 4h18v-2H3v2zm0-8h18V9H3v2zm0-6v2h18V5H3z" />
</SVG>
);
20 changes: 20 additions & 0 deletions packages/block-library/src/post-content/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import metadata from './block.json';
import icon from './icon';
import edit from './edit';

const { name } = metadata;
export { metadata, name };

export const settings = {
title: __( 'Post Content' ),
icon,
edit,
};
4 changes: 4 additions & 0 deletions packages/block-library/src/post-title/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "core/post-title",
"category": "theme"
}
24 changes: 24 additions & 0 deletions packages/block-library/src/post-title/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* WordPress dependencies
*/
import { useEntityProp } from '@wordpress/core-data';
import { RichText } from '@wordpress/block-editor';
import { cleanForSlug } from '@wordpress/editor';
import { __ } from '@wordpress/i18n';

export default function PostTitleEdit() {
const [ title, setTitle ] = useEntityProp( 'post', 'title' );
const [ , setSlug ] = useEntityProp( 'post', 'slug' );
return (
<RichText
value={ title }
onChange={ ( value ) => {
setTitle( value );
setSlug( cleanForSlug( value ) );
} }
tagName="h1"
placeholder={ __( 'Title' ) }
formattingControls={ [] }
/>
);
}
11 changes: 11 additions & 0 deletions packages/block-library/src/post-title/icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* WordPress dependencies
*/
import { SVG, Path } from '@wordpress/components';

export default (
<SVG xmlns="https://www.w3.org/2000/svg" viewBox="0 0 24 24">
<Path fill="none" d="M0 0h24v24H0V0z" />
<Path d="M5 4v3h5.5v12h3V7H19V4H5z" />
</SVG>
);
20 changes: 20 additions & 0 deletions packages/block-library/src/post-title/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import metadata from './block.json';
import icon from './icon';
import edit from './edit';

const { name } = metadata;
export { metadata, name };

export const settings = {
title: __( 'Post Title' ),
icon,
edit,
};
9 changes: 9 additions & 0 deletions packages/block-library/src/post/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "core/post",
"category": "theme",
"attributes": {
"postId": {
"type": "number"
}
}
}
Loading