Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,39 @@ transforms: {
```
{% end %}

A block with innerBlocks can also be transformed from and to another block with innerBlocks.

{% codetabs %}
{% ES5 %}
```js
transforms: {
to: [
{
type: 'block',
blocks: [ 'some/block-with-innerblocks' ],
transform: function( attributes, innerBlocks ) {
return createBlock( 'some/other-block-with-innerblocks', attributes, innerBlocks );
},
},
],
},
```
{% ESNext %}
```js
transforms: {
to: [
{
type: 'block',
blocks: [ 'some/block-with-innerblocks' ],
transform: ( attributes, innerBlocks ) => {
return createBlock( 'some/other-block-with-innerblocks', attributes, innerBlocks);
},
},
],
},
```
{% end %}

An optional `isMatch` function can be specified on a transform object. This provides an opportunity to perform additional checks on whether a transform should be possible. Returning `false` from this function will prevent the transform from being displayed as an option to the user.

{% codetabs %}
Expand Down
6 changes: 6 additions & 0 deletions packages/blocks/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 6.1.0 (Unreleased)

### New Feature

- Blocks' `transforms` will receive `innerBlocks` as the second argument (or an array of each block's respective `innerBlocks` for a multi-transform).

## 6.0.5 (2019-01-03)

## 6.0.4 (2018-12-12)
Expand Down
7 changes: 5 additions & 2 deletions packages/blocks/src/api/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,12 @@ export function switchToBlockType( blocks, name ) {

let transformationResults;
if ( transformation.isMultiBlock ) {
transformationResults = transformation.transform( blocksArray.map( ( currentBlock ) => currentBlock.attributes ) );
transformationResults = transformation.transform(
blocksArray.map( ( currentBlock ) => currentBlock.attributes ),
blocksArray.map( ( currentBlock ) => currentBlock.innerBlocks )
);
} else {
transformationResults = transformation.transform( firstBlock.attributes );
transformationResults = transformation.transform( firstBlock.attributes, firstBlock.innerBlocks );
}

// Ensure that the transformation function returned an object or an array
Expand Down
100 changes: 100 additions & 0 deletions packages/blocks/src/api/test/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,106 @@ describe( 'block factory', () => {
value: 'smoked ribs',
} );
} );

it( 'should pass through inner blocks to transform', () => {
registerBlockType( 'core/updated-columns-block', {
attributes: {
value: {
type: 'string',
},
},
transforms: {
from: [ {
type: 'block',
blocks: [ 'core/columns-block' ],
transform( attributes, innerBlocks ) {
return createBlock(
'core/updated-columns-block',
attributes,
innerBlocks.map( ( innerBlock ) => {
return cloneBlock( innerBlock, {
value: 'after',
} );
} ),
);
},
} ],
},
save: noop,
category: 'common',
title: 'updated columns block',
} );
registerBlockType( 'core/columns-block', defaultBlockSettings );
registerBlockType( 'core/column-block', defaultBlockSettings );

const block = createBlock(
'core/columns-block',
{},
[ createBlock( 'core/column-block', { value: 'before' } ) ]
);

const transformedBlocks = switchToBlockType( block, 'core/updated-columns-block' );

expect( transformedBlocks ).toHaveLength( 1 );
expect( transformedBlocks[ 0 ].innerBlocks ).toHaveLength( 1 );
expect( transformedBlocks[ 0 ].innerBlocks[ 0 ].attributes.value ).toBe( 'after' );
} );

it( 'should pass through inner blocks to transform (multi)', () => {
registerBlockType( 'core/updated-columns-block', {
attributes: {
value: {
type: 'string',
},
},
transforms: {
from: [ {
type: 'block',
blocks: [ 'core/columns-block' ],
isMultiBlock: true,
transform( blocksAttributes, blocksInnerBlocks ) {
return blocksAttributes.map( ( attributes, i ) => {
return createBlock(
'core/updated-columns-block',
attributes,
blocksInnerBlocks[ i ].map( ( innerBlock ) => {
return cloneBlock( innerBlock, {
value: 'after' + i,
} );
} ),
);
} );
},
} ],
},
save: noop,
category: 'common',
title: 'updated columns block',
} );
registerBlockType( 'core/columns-block', defaultBlockSettings );
registerBlockType( 'core/column-block', defaultBlockSettings );

const blocks = [
createBlock(
'core/columns-block',
{},
[ createBlock( 'core/column-block', { value: 'before' } ) ]
),
createBlock(
'core/columns-block',
{},
[ createBlock( 'core/column-block', { value: 'before' } ) ]
),
];

const transformedBlocks = switchToBlockType( blocks, 'core/updated-columns-block' );

expect( transformedBlocks ).toHaveLength( 2 );
expect( transformedBlocks[ 0 ].innerBlocks ).toHaveLength( 1 );
expect( transformedBlocks[ 0 ].innerBlocks[ 0 ].attributes.value ).toBe( 'after0' );
expect( transformedBlocks[ 1 ].innerBlocks ).toHaveLength( 1 );
expect( transformedBlocks[ 1 ].innerBlocks[ 0 ].attributes.value ).toBe( 'after1' );
} );
} );

describe( 'getBlockTransforms', () => {
Expand Down
71 changes: 58 additions & 13 deletions packages/e2e-tests/plugins/inner-blocks-templates/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
( function() {
var registerBlockType = wp.blocks.registerBlockType;
var createBlock = wp.blocks.createBlock;
var el = wp.element.createElement;
var InnerBlocks = wp.editor.InnerBlocks;
var __ = wp.i18n.__;
Expand Down Expand Up @@ -28,10 +29,10 @@

edit: function( props ) {
return el(
InnerBlocks,
{
template: TEMPLATE,
}
InnerBlocks,
{
template: TEMPLATE,
}
);
},

Expand All @@ -45,11 +46,11 @@

edit: function( props ) {
return el(
InnerBlocks,
{
template: TEMPLATE,
templateLock: 'all',
}
InnerBlocks,
{
template: TEMPLATE,
templateLock: 'all',
}
);
},

Expand All @@ -63,13 +64,57 @@

edit: function( props ) {
return el(
InnerBlocks,
{
template: TEMPLATE_PARAGRAPH_PLACEHOLDER,
}
InnerBlocks,
{
template: TEMPLATE_PARAGRAPH_PLACEHOLDER,
}
);
},

save,
} );

registerBlockType( 'test/test-inner-blocks-transformer-target', {
title: 'Test Inner Blocks transformer target',
icon: 'cart',
category: 'common',

transforms: {
from: [
{
type: 'block',
blocks: [
'test/i-dont-exist',
'test/test-inner-blocks-no-locking',
'test/test-inner-blocks-locking-all',
'test/test-inner-blocks-paragraph-placeholder'
],
transform: function( attributes, innerBlocks ) {
return createBlock( 'test/test-inner-blocks-transformer-target', attributes, innerBlocks );
},
},
],
to: [
{
type: 'block',
blocks: [ 'test/i-dont-exist' ],
transform: function( attributes, innerBlocks ) {
return createBlock( 'test/test-inner-blocks-transformer-target', attributes, innerBlocks );
},
}
]
},

edit: function( props ) {
return el(
InnerBlocks,
{
template: TEMPLATE,
}
);
},

save,
} );

} )();