-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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 Templates: Check the validity of the block list against the defined template #5162
Conversation
|
||
return ( | ||
<Notice isDismissible={ false } status="warning"> | ||
<div className="editor-template-notice"> |
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.
Could we update Notice
to apply an optional className
prop?
editor/store/actions.js
Outdated
* | ||
* @return {Object} Action object. | ||
*/ | ||
export function setupEditorState( post, blocks, edits ) { | ||
export function setupEditorState( post, blocks, edits, isValidTemplate ) { |
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'm not sure this needs to be part of setupEditorState
, particularly because it's not part of state.editor
like the others are (and notably the others needing to be bulked together for undo/dirtying reasons).
}, | ||
onPersist( content ) { | ||
return resetBlocks( parse( content ) ); |
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.
We use redux-multi
, so this could have been updated to return as an array.
blocks/api/templates.js
Outdated
* @return {boolean} Whether the list of blocks matches a templates | ||
*/ | ||
export function doesBlocksMatchTemplate( blocks = [], template = [] ) { | ||
return blocks.length === template.length && every( template, ( [ name,, innerBlocksTemplate ], index ) => { |
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.
Aversion to long lines makes me wish this was:
if ( blocks.length !== template.length ) {
return false;
}
return every( /* ... */ );
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.
These double commas can be easy to overlook. Personally I add a blank space between them, though not really sure it's any better. Thoughts?
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 added a space, I agree it's not common so it should be more visible.
* | ||
* @return {Array} Updated Block list. | ||
*/ | ||
export function synchronizeBlocksWithTemplate( blocks = [], template = [] ) { |
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 function name "sounds" mutative. Not sure I have a better alternative.. maybe getSynchronizedTemplate
?
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 the blocks
should be in the name somehow, because it doesn't return a template, it returns blocks.
d760bd2
to
2f8cc52
Compare
blocks/api/templates.js
Outdated
* | ||
* @return {boolean} Whether the list of blocks matches a templates | ||
*/ | ||
export function doesBlocksMatchTemplate( blocks = [], template = [] ) { |
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 should be doBlocksMatch...
* @return {Array} Updated Block list. | ||
*/ | ||
export function synchronizeBlocksWithTemplate( blocks = [], template = [] ) { | ||
return map( template, ( [ name, attributes, innerBlocksTemplate ], index ) => { |
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'd be good to explain what happens to blocks (content) when they are synced.
@@ -0,0 +1,50 @@ | |||
/** |
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 template-validation-notice
.
editor/store/effects.js
Outdated
if ( post.content.raw ) { | ||
blocks = parse( post.content.raw ); | ||
isValidTemplate = ( |
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.
Wonder if we should mention here we only validate templates that are defined as "locked".
Just to understand, this means when you create a template where adding or removing blocks is not allowed, correct? Looking at this: What happens if you press "Keep as is" and reload the page? Do you get the banner back? What if you accidentally pressed "Keep as is" and then regret it? What happens if you press "Reset Template"? Not asking as critique, just want to understand fully before I can help with design feedback. Thanks. |
Yes, you get it back.
Blocks that match the template are kept the onces that don't are removed. I expect this feature (locked templates) to be used with blocks saving to post meta which means in general, you won't lose anything, maybe you just added a new meta block and it will show up or you moved your meta blocks around. |
Could you could step back to an older revision if you lost some content? |
You can undo if it's not saved, and if it's saved, there's always revisions :) |
Not sure if this'll be the case. I can see many locked templates that just want to define an initial shape. Might be worth considering to support migrations for individual blocks within a template. |
Not sure how to move forward here? Is there anything missing? Do we disagree with the idea entirely? |
Sorry, let's get it in as it applies to locked templates alone. |
26488c5
to
bbfb64f
Compare
bbfb64f
to
68eaeca
Compare
Fixes #4476
When editing a post, the template is ignored entirely which means that if you update the template and opens an existing post in the editor, the template won't be updated.
This PR adds a mechanism to check the content of the current post against the template. The check is considered valid if all the block names of the content match the block names of the template.
If the check is invalid a notice is displayed inviting the user to reset its post according to the template (which could restult in some content loss) or keep the content as is.
If you edit the post in the text editor, the check is also performed.
Note This PR is necessary in order to achieve nested template locking because we want to match which container block has which lock config in the template.
Testing instructions
You can make use of the GCF plugin to test this quickly.