Skip to content

Instantly share code, notes, and snippets.

@bfintal
Created September 29, 2021 12:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bfintal/be97d3182a69747ee937cad3b6bc98b3 to your computer and use it in GitHub Desktop.
Save bfintal/be97d3182a69747ee937cad3b6bc98b3 to your computer and use it in GitHub Desktop.
Encountering lots of broken blocks / block errors in WordPress Gutenberg? Paste this code in your browser developer console while editing your post to recover all the blocks at once.
var recursivelyRecoverInvalidBlockList = blocks => {
const _blocks = [ ...blocks ]
let recoveryCalled = false
const recursivelyRecoverBlocks = willRecoverBlocks => {
willRecoverBlocks.forEach( _block => {
if ( isInvalid( _block ) ) {
recoveryCalled = true
const newBlock = recoverBlock( _block )
for ( const key in newBlock ) {
_block[ key ] = newBlock[ key ]
}
}
if ( _block.innerBlocks.length ) {
recursivelyRecoverBlocks( _block.innerBlocks )
}
} )
}
recursivelyRecoverBlocks( _blocks )
return [ _blocks, recoveryCalled ]
}
var recoverBlock = ( { name, attributes, innerBlocks } ) =>
wp.blocks.createBlock( name, attributes, innerBlocks );
var recoverBlocks = blocks => {
return blocks.map( _block => {
const block = _block
// If the block is a reusable block, recover the Stackable blocks inside it.
if ( _block.name === 'core/block' ) {
const { attributes: { ref } } = _block
const parsedBlocks = wp.blocks.parse( wp.data.select( 'core' ).getEntityRecords( 'postType', 'wp_block', { include: [ ref ] } )?.[ 0 ]?.content?.raw ) || []
const [ recoveredBlocks, recoveryCalled ] = recursivelyRecoverInvalidBlockList( parsedBlocks )
if ( recoveryCalled ) {
console.log( 'Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.' ) // eslint-disable-line no-console
return {
blocks: recoveredBlocks,
isReusable: true,
ref,
}
}
}
if ( block.innerBlocks && block.innerBlocks.length ) {
const newInnerBlocks = recoverBlocks( block.innerBlocks )
if ( newInnerBlocks.some( block => block.recovered ) ) {
block.innerBlocks = newInnerBlocks
block.replacedClientId = block.clientId
block.recovered = true
}
}
if ( ! block.isValid ) {
const newBlock = recoverBlock( block )
newBlock.replacedClientId = block.clientId
newBlock.recovered = true
console.log( 'Stackable notice: block ' + block.name + ' (' + block.clientId + ') was auto-recovered, you should not see this after saving your page.' ) // eslint-disable-line no-console
return newBlock
}
return block
} )
}
// Recover all the blocks that we can find.
var mainBlocks = recoverBlocks( wp.data.select( 'core/editor' ).getEditorBlocks() )
// Replace the recovered blocks with the new ones.
mainBlocks.forEach( block => {
if ( block.isReusable && block.ref ) {
// Update the reusable blocks.
wp.data.dispatch( 'core' ).editEntityRecord( 'postType', 'wp_block', block.ref, { content: wp.blocks.serialize( block.blocks ) } ).then( () => {
// But don't save them, let the user do the saving themselves. Our goal is to get rid of the block error visually.
// dispatch( 'core' ).saveEditedEntityRecord( 'postType', 'wp_block', block.ref )
} )
}
if ( block.recovered && block.replacedClientId ) {
wp.data.dispatch( 'core/block-editor' ).replaceBlock( block.replacedClientId, block )
}
} )
@Ahiaz
Copy link

Ahiaz commented Oct 18, 2022

Hello, a query, I have a gutenberg block on many posts, is it possible to run this command on all the posts, without having to open them one by one?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment