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

Blocks: Refactor blocks to use supports align #5099

Closed
wants to merge 7 commits into from

Conversation

gziolo
Copy link
Member

@gziolo gziolo commented Feb 16, 2018

Description

Follow up for #4069.

This PR seeks the way to refactor all existing core block to use newly introduced align option for inside supports field. It also adds missing changes to the documentation.

I skipped 3 4 blocks which use non-standard properties:

  • image
  • paragraph
  • text-columns
  • latests-posts

We may leave it as it is or we can tackle in another PR.

How to test

For testing purpose it makes sense to enable wide alignment as described here.

Verify that there are no regressions in the alignment behavior of the following blocks:

Ensure unit tests pass:

npm test

Types of changes

Refactoring.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code has proper inline documentation.

@gziolo gziolo added [Feature] Blocks Overall functionality of blocks [Status] In Progress Tracking issues with work in progress labels Feb 16, 2018
@gziolo gziolo self-assigned this Feb 16, 2018
@gziolo gziolo requested a review from aduth February 16, 2018 13:06
@gziolo gziolo force-pushed the update/blocks-supports-align branch 4 times, most recently from cdd5657 to 3d51715 Compare February 16, 2018 14:02
@@ -24,7 +24,7 @@ import { getBlockSupport, hasBlockSupport } from '../api';
* @return {Object} Filtered block settings
*/
export function addAttribute( settings ) {
if ( hasBlockSupport( settings, 'align' ) ) {
if ( hasBlockSupport( settings, 'align' ) && ! has( settings, [ 'attributes', 'align' ] ) ) {
Copy link
Member Author

Choose a reason for hiding this comment

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

It would be nice to avoid this workaround. I added to make sure that tests pass, which gave me an impression that it might trigger some warnings in the browser when loading old posts.

Copy link
Member

Choose a reason for hiding this comment

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

The failing tests I'm seeing when removing this workaround seem legitimately concerning though?

Expected:
    
    <blockquote class=\"wp-block-pullquote alignundefined\"

Why would alignundefined be expected?

Worth looking into...

Copy link
Member

Choose a reason for hiding this comment

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

Some of the failures could also be cleared up by running npm run fixtures:regenerate (specifically, the _domReact key changes)

edit( { attributes, setAttributes, className, focus } ) {
const { align, columns } = attributes;
const { columns } = attributes;
const classes = classnames( className, `has-${ columns }-columns` );

return [
...focus ? [
Copy link
Member Author

Choose a reason for hiding this comment

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

@youknowriad should we replace ...focus with isSelected?

Copy link
Contributor

Choose a reason for hiding this comment

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

Definitely

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated 👍

@@ -127,36 +127,52 @@ useOnce: true,

* **Type:** `Object`

Optional block extended support features. The following options are supported, and should be specified as a boolean `true` or `false` value:
Optional block extended support features. The following options are supported, and should be specified as a boolean `true` or `false` value in most of the cases:
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure how to better phrase this exception for an array :)

Copy link
Member

Choose a reason for hiding this comment

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

Maybe avoid the second part of the sentence, just leaving:

Optional block extended support features. The following options are supported:

Copy link
Member Author

Choose a reason for hiding this comment

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

😃

@gziolo gziolo added [Feature] Extensibility The ability to extend blocks or the editing experience and removed [Status] In Progress Tracking issues with work in progress labels Feb 16, 2018
@gziolo gziolo force-pushed the update/blocks-supports-align branch from 3d51715 to 5c261c4 Compare February 16, 2018 14:36
} }
/>
</BlockControls>,
isSelected ? [
Copy link
Member

Choose a reason for hiding this comment

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

Since there's only a single entry, this could be simplified to:

isSelected && (

Also dropping the key from InspectorControls

@@ -127,36 +127,52 @@ useOnce: true,

* **Type:** `Object`

Optional block extended support features. The following options are supported, and should be specified as a boolean `true` or `false` value:
Optional block extended support features. The following options are supported, and should be specified as a boolean `true` or `false` value in most of the cases:
Copy link
Member

Choose a reason for hiding this comment

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

Maybe avoid the second part of the sentence, just leaving:

Optional block extended support features. The following options are supported:

/>
</BlockControls>
),
return (
<blockquote key="quote" className={ className }>
Copy link
Member

Choose a reason for hiding this comment

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

key unnecessary.

</BlockControls>
),

return (
<TableBlock
key="editor"
Copy link
Member

Choose a reason for hiding this comment

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

key unnecessary.

html: false,
```

- `wideAlign` (default `true`): Gutenberg allows to enable [wide alignment](themes.md#wide-alignment) for your theme. To disable this behavior for a single block, set this flag to `false`.
Copy link
Member

Choose a reason for hiding this comment

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

This link won't work when ported to the WordPress.org handbook. It needs to be an absolute URL.

html: false,
```

- `wideAlign` (default `true`): Gutenberg allows to enable [wide alignment](themes.md#wide-alignment) for your theme. To disable this behavior for a single block, set this flag to `false`.

```js
Copy link
Member

Choose a reason for hiding this comment

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

Missing the closing ```

@@ -186,8 +166,7 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k
typeClassName += ' is-video';
}

return [
controls,
return (
<figure key="embed" className={ typeClassName }>
Copy link
Member

Choose a reason for hiding this comment

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

key unnecessary.

}

if ( ! html ) {
const label = sprintf( __( '%s URL' ), title );

return [
controls,
return (
<Placeholder key="placeholder" icon={ icon } label={ label } className="wp-block-embed">
Copy link
Member

Choose a reason for hiding this comment

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

key unnecessary.

const props = {};
supports: {
align: true,
wideAlign: false,
Copy link
Member

Choose a reason for hiding this comment

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

Why wideAlign: false? Seems to be allowed in master.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's broken in master though :) Styles aren't applied for full and wide properly... We can fix that.

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 don't think it is designed to work with the theme option alignWide.

By the way, we should rename wideAlign to alignWide to match with PHP.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is how wide looks like in action:
screen shot 2018-02-19 at 11 51 19
screen shot 2018-02-19 at 11 51 30

Let's leave it disabled for the time being. @karmatosed @jasmussen any plans to make button block wide aligned?

@gziolo gziolo force-pushed the update/blocks-supports-align branch from 5c261c4 to 2823dab Compare February 19, 2018 13:46
@jasmussen
Copy link
Contributor

Can't find the particular discussion now, the deeplink didn't work. But a question was asked: should the button support wide alignments? The answer is probably not. The button is good for centering and floating, but it is likely to shine once it can live as a nested block inside containers. At that point you might start to create some reusable blocks that could feature perhaps an image, some text, and a button, all nested inside a single "box" block or whatever we end up calling it. This box block would then support wide alignments, and the content inside would scale to that. But it doesn't seem like there's a huge value in having these alignments on the button itself.

@gziolo
Copy link
Member Author

gziolo commented Feb 19, 2018

@jasmussen, thanks for the confirmation. @aduth this is ready for another check. I addressed all comments.

aduth
aduth previously requested changes Feb 19, 2018
@@ -24,7 +24,7 @@ import { getBlockSupport, hasBlockSupport } from '../api';
* @return {Object} Filtered block settings
*/
export function addAttribute( settings ) {
if ( hasBlockSupport( settings, 'align' ) ) {
if ( hasBlockSupport( settings, 'align' ) && ! has( settings, [ 'attributes', 'align' ] ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

The failing tests I'm seeing when removing this workaround seem legitimately concerning though?

Expected:
    
    <blockquote class=\"wp-block-pullquote alignundefined\"

Why would alignundefined be expected?

Worth looking into...

</blockquote>,
];
</blockquote>
);
} ),

save( { attributes } ) {
Copy link
Member

Choose a reason for hiding this comment

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

The save implementation should no longer be responsible for applying the align class.

Same goes for all other refactored blocks.

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 missed that, good catch 👍

@@ -24,7 +24,7 @@ import { getBlockSupport, hasBlockSupport } from '../api';
* @return {Object} Filtered block settings
*/
export function addAttribute( settings ) {
if ( hasBlockSupport( settings, 'align' ) ) {
if ( hasBlockSupport( settings, 'align' ) && ! has( settings, [ 'attributes', 'align' ] ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

Some of the failures could also be cleared up by running npm run fixtures:regenerate (specifically, the _domReact key changes)

@@ -92,7 +92,6 @@ function register_block_core_latest_posts() {
),
'align' => array(
'type' => 'string',
'default' => 'center',
Copy link
Member Author

Choose a reason for hiding this comment

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

This one is tricky because we set all attributes using PHP code, but then override with JavaScript using hook. Should we add deprecation block for this case? /cc @youknowriad

@@ -2,7 +2,7 @@

exports[`core/text-columns block edit matches snapshot 1`] = `
<div
class="wp-block-text-columns alignundefined columns-2"
class="wp-block-text-columns columns-2"
Copy link
Member Author

Choose a reason for hiding this comment

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

alignundefined doesn't make too much sense, that's why used classnames to fix this.

@@ -131,7 +131,7 @@ export function withAlign( BlockListBlock ) {
export function addAssignedAlign( props, blockType, attributes ) {
const { align } = attributes;

if ( includes( getBlockValidAlignments( blockType ), align ) ) {
if ( align && includes( getBlockValidAlignments( blockType ), align ) ) {
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 this is where alignundefined could be generated before this commit.

Copy link
Member

Choose a reason for hiding this comment

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

But... how? Looking through getBlockValidAlignments, I can't envision any scenario where it should return an array with undefined as an entry.

And if it does, that sounds like a bug with getBlockValidAlignments.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ooops, you are right. It is obsolete unless we want to add performance optimization to avoid array lookup :P I'm removing this change.

@gziolo
Copy link
Member Author

gziolo commented Feb 20, 2018

I regenerated tests and applied a few tweaks with a3ceee5.

@gziolo gziolo force-pushed the update/blocks-supports-align branch from a186cdf to a3ceee5 Compare February 20, 2018 20:35
@@ -131,7 +131,7 @@ export function withAlign( BlockListBlock ) {
export function addAssignedAlign( props, blockType, attributes ) {
const { align } = attributes;

if ( includes( getBlockValidAlignments( blockType ), align ) ) {
if ( align && includes( getBlockValidAlignments( blockType ), align ) ) {
Copy link
Member

Choose a reason for hiding this comment

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

But... how? Looking through getBlockValidAlignments, I can't envision any scenario where it should return an array with undefined as an entry.

And if it does, that sounds like a bug with getBlockValidAlignments.

@@ -67,18 +65,12 @@ class ButtonBlock extends Component {
text,
url,
title,
align,
color,
textColor,
clear,
} = attributes;

return [
Copy link
Member

Choose a reason for hiding this comment

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

This no longer needs to be returned as an array.

Copy link
Member Author

@gziolo gziolo Feb 22, 2018

Choose a reason for hiding this comment

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

There is an optional form in line 117: https://github.com/WordPress/gutenberg/blob/a3ceee55afbe0200a1567945e14de6f3b3f14f61/blocks/library/button/index.js#L117. It only seems that you can omit array structure here :)

<BlockControls key="controls">
<BlockAlignmentToolbar value={ align } onChange={ this.updateAlignment } />
</BlockControls>
),
<span key="button" className={ className } title={ title } ref={ this.bindRef }>
Copy link
Member

Choose a reason for hiding this comment

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

And this will no longer need key when not returned as part of an array.

Copy link
Member Author

Choose a reason for hiding this comment

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

See my previous comment.

props[ 'data-align' ] = align;
}
getEditWrapperProps( { clear } ) {
const props = {};
Copy link
Member

Choose a reason for hiding this comment

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

Since getEditWrapperProps can return undefined, this could potentially be simplified to:

getEditWrapperProps( { clear } ) {
	if ( clear ) {
		return { 'data-clear': 'true' };
	}
}

@@ -210,7 +198,7 @@ export const settings = {
const linkClass = 'wp-block-button__link';

return (
<div className={ `align${ align }` }>
Copy link
Member

Choose a reason for hiding this comment

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

This is the only unfortunate thing about these "magic" supports. It becomes very non-obvious why we need the div wrapper at all.

Copy link
Member Author

@gziolo gziolo Feb 22, 2018

Choose a reason for hiding this comment

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

Yes, this might have up to 3 class names inserted in here :)

attributes: blockAttributes,
attributes: {
...blockAttributes,
align: {
Copy link
Member

Choose a reason for hiding this comment

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

Since a deprecated entry supports supports, could we just include align there?

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 don't think it will work. The deprecated entry doesn't copy attributes, supports and save: ...omit( blockType, [ 'attributes', 'save', 'supports' ] ). Hooks we have with the current implementation don't modify the deprecated block types. @youknowriad can you confirm if the current implementation is valid?

</BlockControls>,
<InspectorControls key="inspector">
isSelected && (
<InspectorControls>
Copy link
Member

Choose a reason for hiding this comment

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

I might have made the opposite claim previously, but since this is now part of the top-level return array, won't this need a key?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it needs :)

return (
<ul className={ `align${ align } columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }` } >
<ul className={ `columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }` } >
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to your changes, but this is begging for classnames 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Let's add in this PR this change, too 👍

@@ -91,8 +91,7 @@ function register_block_core_latest_posts() {
'default' => 3,
),
'align' => array(
'type' => 'string',
'default' => 'center',
'type' => 'string',
Copy link
Member

Choose a reason for hiding this comment

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

Oof... did we decide anything about how we're going to handle server attributes for supports properties, particularly if we're planning for server-registered attributes to become the canonical set?

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 will revert all changes for the latest posts block, as this is falls under special case group :) We can tackle it later.

Copy link
Member Author

@gziolo gziolo Feb 22, 2018

Choose a reason for hiding this comment

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

So this one is tricky. It is exposed with the global variable and consumed when the block is registered, but it is not that easy to ensure it behaves the same in the JS and PHP context. We might want to revisit the idea of using has check as I proposed earlier: #5099 (comment):

if ( hasBlockSupport( settings, 'align' ) && ! has( settings, [ 'attributes', 'align' ] ) ) {

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 I will revert all changes for the latest posts block, as this is falls under special case group :) We can tackle it later.

I think we ought to at least have a strategy, because I'm starting to worry that these supports which add attributes may be non-viable altogether. Or do you think it's just a matter of duplicating the logic in the server?

Copy link
Member Author

Choose a reason for hiding this comment

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

The issue here is that you need to define this attribute on the server to make it exposed to the save function when server-side rendering your block. This is a general issue with such blocks, there is lots of duplication. I think we should tackle all similar issues as a whole, not necessarily as part of this refactoring.

One way of dealing with it would be to mark a component as handled server-side. However it still doesn't solve the issue of code duplication, because we end up in a situation where edit is handled client-side, but save mostly server-side. I don't think we can completely switch over to the solution where this is cleanly separated. We can only mitigate the unexpected side-effects where we set something on the client but it isn't passed back to the server.

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 we should tackle all similar issues as a whole, not necessarily as part of this refactoring.

I'm personally considering it a blocker because I'm not convinced yet there's a solution at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

@youknowriad, @mtias or @mcsf, any ideas how to unblock it? :) The only thing I can come up is to avoid adding align to attributes if it was already provided server-side, but it doesn't solve the root of the problem. We need to make some decisions how do we handle server-side rendered blocks. The main question is how much duplication are we happy to introduce between PHP and JS?

@gziolo gziolo force-pushed the update/blocks-supports-align branch 2 times, most recently from cbf452f to 04e670b Compare February 22, 2018 11:24
@gziolo
Copy link
Member Author

gziolo commented Feb 22, 2018

As discussed in #5099 (comment), I removed all changes to the latest posts block from this PR. This PR is big enough so let's tackle all 4 remaining blocks that have a non-standard block alignment in the follow-up PRs.

@gziolo gziolo force-pushed the update/blocks-supports-align branch from 04e670b to f903bb0 Compare February 28, 2018 09:18
@gziolo gziolo dismissed aduth’s stale review February 28, 2018 10:03

I rebased with master and addressed all comment. I plan to merge it tomorrow, if you agree.

@jeffpaul jeffpaul added this to the Merge Proposal milestone Mar 15, 2018
@karmatosed karmatosed modified the milestones: Merge Proposal, Merge Proposal: Plugins Apr 12, 2018
@gziolo
Copy link
Member Author

gziolo commented Apr 24, 2018

It's on hold since we didn't agree how to tackle server-side rendered blocks.

@gziolo
Copy link
Member Author

gziolo commented May 2, 2018

Closing this one as it became stale and would require lots of work to make it up to date, given all the changes introduced in the meantime. We still didn't come up with a solution how to tackle server-side rendered blocks. In addition, there were another smaller PRs which added align support for the individual blocks (like #6364) or other where we remove support for align at all (like #6511)...

@gziolo gziolo closed this May 2, 2018
@gziolo gziolo deleted the update/blocks-supports-align branch May 2, 2018 08:07
@designsimply designsimply added the [Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed. label Jul 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Blocks Overall functionality of blocks [Feature] Extensibility The ability to extend blocks or the editing experience [Status] Stale Gives the original author opportunity to update before closing. Can be reopened as needed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants