-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Conversation
cdd5657
to
3d51715
Compare
blocks/hooks/align.js
Outdated
@@ -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' ] ) ) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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)
blocks/library/columns/index.js
Outdated
edit( { attributes, setAttributes, className, focus } ) { | ||
const { align, columns } = attributes; | ||
const { columns } = attributes; | ||
const classes = classnames( className, `has-${ columns }-columns` ); | ||
|
||
return [ | ||
...focus ? [ |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated 👍
docs/block-api.md
Outdated
@@ -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: |
There was a problem hiding this comment.
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 :)
There was a problem hiding this comment.
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:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😃
3d51715
to
5c261c4
Compare
blocks/library/columns/index.js
Outdated
} } | ||
/> | ||
</BlockControls>, | ||
isSelected ? [ |
There was a problem hiding this comment.
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
docs/block-api.md
Outdated
@@ -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: |
There was a problem hiding this comment.
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:
blocks/library/pullquote/index.js
Outdated
/> | ||
</BlockControls> | ||
), | ||
return ( | ||
<blockquote key="quote" className={ className }> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key
unnecessary.
blocks/library/table/index.js
Outdated
</BlockControls> | ||
), | ||
|
||
return ( | ||
<TableBlock | ||
key="editor" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key
unnecessary.
docs/block-api.md
Outdated
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`. |
There was a problem hiding this comment.
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.
docs/block-api.md
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing the closing ```
blocks/library/embed/index.js
Outdated
@@ -186,8 +166,7 @@ function getEmbedBlockSettings( { title, icon, category = 'embed', transforms, k | |||
typeClassName += ' is-video'; | |||
} | |||
|
|||
return [ | |||
controls, | |||
return ( | |||
<figure key="embed" className={ typeClassName }> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key
unnecessary.
blocks/library/embed/index.js
Outdated
} | ||
|
||
if ( ! html ) { | ||
const label = sprintf( __( '%s URL' ), title ); | ||
|
||
return [ | ||
controls, | ||
return ( | ||
<Placeholder key="placeholder" icon={ icon } label={ label } className="wp-block-embed"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key
unnecessary.
blocks/library/button/index.js
Outdated
const props = {}; | ||
supports: { | ||
align: true, | ||
wideAlign: false, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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:
Let's leave it disabled for the time being. @karmatosed @jasmussen any plans to make button block wide aligned?
5c261c4
to
2823dab
Compare
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. |
@jasmussen, thanks for the confirmation. @aduth this is ready for another check. I addressed all comments. |
blocks/hooks/align.js
Outdated
@@ -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' ] ) ) { |
There was a problem hiding this comment.
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 } ) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 👍
blocks/hooks/align.js
Outdated
@@ -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' ] ) ) { |
There was a problem hiding this comment.
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)
2680225
to
a186cdf
Compare
@@ -92,7 +92,6 @@ function register_block_core_latest_posts() { | |||
), | |||
'align' => array( | |||
'type' => 'string', | |||
'default' => 'center', |
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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.
blocks/hooks/align.js
Outdated
@@ -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 ) ) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
I regenerated tests and applied a few tweaks with a3ceee5. |
a186cdf
to
a3ceee5
Compare
blocks/hooks/align.js
Outdated
@@ -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 ) ) { |
There was a problem hiding this comment.
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 [ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 }> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my previous comment.
blocks/library/button/index.js
Outdated
props[ 'data-align' ] = align; | ||
} | ||
getEditWrapperProps( { clear } ) { | ||
const props = {}; |
There was a problem hiding this comment.
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 }` }> |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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: { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
blocks/library/columns/index.js
Outdated
</BlockControls>, | ||
<InspectorControls key="inspector"> | ||
isSelected && ( | ||
<InspectorControls> |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it needs :)
blocks/library/gallery/index.js
Outdated
return ( | ||
<ul className={ `align${ align } columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }` } > | ||
<ul className={ `columns-${ columns } ${ imageCrop ? 'is-cropped' : '' }` } > |
There was a problem hiding this comment.
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
😄
There was a problem hiding this comment.
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', |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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' ] ) ) {
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
cbf452f
to
04e670b
Compare
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. |
04e670b
to
f903bb0
Compare
I rebased with master and addressed all comment. I plan to merge it tomorrow, if you agree.
It's on hold since we didn't agree how to tackle server-side rendered blocks. |
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 |
Description
Follow up for #4069.
This PR seeks the way to refactor all existing core block to use newly introduced
align
option for insidesupports
field. It also adds missing changes to the documentation.I skipped
34 blocks which use non-standard properties: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:
latest posts- removed from this PR, see: Blocks: Refactor blocks to use supports align #5099 (comment)Ensure unit tests pass:
Types of changes
Refactoring.
Checklist: