-
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: Support block nesting (Add Columns block, InnerBlocks component) #3745
Changes from all commits
dea003b
acb160e
86fd2bc
2f556b3
38165b9
80d66e6
06252a1
1dd6f6f
377a1f2
60c7158
326cdac
ab4be6a
31a2ce0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { hasFilter, applyFilters } from '@wordpress/hooks'; | |
* Internal dependencies | ||
*/ | ||
import { getBlockType, getUnknownTypeHandlerName } from './registration'; | ||
import BlockContentProvider from '../block-content-provider'; | ||
|
||
/** | ||
* Returns the block's default classname from its name. | ||
|
@@ -32,12 +33,13 @@ export function getBlockDefaultClassname( blockName ) { | |
* Given a block type containg a save render implementation and attributes, returns the | ||
* enhanced element to be saved or string when raw HTML expected. | ||
* | ||
* @param {Object} blockType Block type. | ||
* @param {Object} attributes Block attributes. | ||
* @param {Object} blockType Block type. | ||
* @param {Object} attributes Block attributes. | ||
* @param {?Array} innerBlocks Nested blocks. | ||
* | ||
* @return {Object|string} Save content. | ||
* @return {Object|string} Save element or raw HTML string. | ||
*/ | ||
export function getSaveElement( blockType, attributes ) { | ||
export function getSaveElement( blockType, attributes, innerBlocks = [] ) { | ||
let { save } = blockType; | ||
|
||
// Component classes are unsupported for save since serialization must | ||
|
@@ -48,7 +50,7 @@ export function getSaveElement( blockType, attributes ) { | |
save = instance.render.bind( instance ); | ||
} | ||
|
||
let element = save( { attributes } ); | ||
let element = save( { attributes, innerBlocks } ); | ||
|
||
if ( isObject( element ) && hasFilter( 'blocks.getSaveContent.extraProps' ) ) { | ||
/** | ||
|
@@ -77,20 +79,27 @@ export function getSaveElement( blockType, attributes ) { | |
* @param {WPBlockType} blockType Block type definition. | ||
* @param {Object} attributes Block attributes. | ||
*/ | ||
return applyFilters( 'blocks.getSaveElement', element, blockType, attributes ); | ||
element = applyFilters( 'blocks.getSaveElement', element, blockType, attributes ); | ||
|
||
return ( | ||
<BlockContentProvider innerBlocks={ innerBlocks }> | ||
{ element } | ||
</BlockContentProvider> | ||
); | ||
} | ||
|
||
/** | ||
* Given a block type containg a save render implementation and attributes, returns the | ||
* static markup to be saved. | ||
* | ||
* @param {Object} blockType Block type. | ||
* @param {Object} attributes Block attributes. | ||
* @param {Object} blockType Block type. | ||
* @param {Object} attributes Block attributes. | ||
* @param {?Array} innerBlocks Nested blocks. | ||
* | ||
* @return {string} Save content. | ||
*/ | ||
export function getSaveContent( blockType, attributes ) { | ||
return renderToString( getSaveElement( blockType, attributes ) ); | ||
export function getSaveContent( blockType, attributes, innerBlocks ) { | ||
return renderToString( getSaveElement( blockType, attributes, innerBlocks ) ); | ||
} | ||
|
||
/** | ||
|
@@ -171,11 +180,14 @@ export function getBlockContent( block ) { | |
const blockType = getBlockType( block.name ); | ||
|
||
// If block was parsed as invalid or encounters an error while generating | ||
// save content, use original content instead to avoid content loss. | ||
// save content, use original content instead to avoid content loss. If a | ||
// block contains nested content, exempt it from this condition because we | ||
// otherwise have no access to its original content and content loss would | ||
// still occur. | ||
let saveContent = block.originalContent; | ||
if ( block.isValid ) { | ||
if ( block.isValid || block.innerBlocks.length ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, If I understand properly we're ignoring the validation because we can't validate properly the container blocks? Can you explain a bit more why we can't validate the container blocks properly? (I'm certain you already did elsewhere, just a link maybe :)) Why are we creating a difference between blocks with inner blocks and blocks without inner blocks. If we can't guarantee the behavior for all blocks, shouldn't we just remove the condition to make it consistent? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main issue is that if we mark the block as invalid, it will defer the next save to using its There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, that we'd be validating the same content n-times. |
||
try { | ||
saveContent = getSaveContent( blockType, block.attributes ); | ||
saveContent = getSaveContent( blockType, block.attributes, block.innerBlocks ); | ||
} catch ( error ) {} | ||
} | ||
|
||
|
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.
How was it being created otherwise?
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 see it was already present just in a different moment.