最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

In a block transform, how do I insert innerBlocks?

programmeradmin2浏览0评论

I am creating a block which is created when transformed from a shortcode. In other words, this:

[example att1="foo" att2="bar"]
    <p>Inner.</p>
    <p>Content.</p>
[/example]

should transform into this a myplugin/example block with inner blocks of the two p tags.

So far I've got this, which works fine to get the shortcode attributes.

(function(wp){

    wp.blocks.registerBlockType( 'myplugin/example', {
        ...

        attributes: {
            att1 {
                type: 'string',
                default: '',
            },
            att2: {
                type: 'string',
                default: '',
            },
        }, 

        transforms: {
            from: [
                {
                    type: 'shortcode',
                    tag: 'example',
                    attributes: {
                        att1: {
                            type: 'string',
                            shortcode: attributes => {
                                return attributes.named.att1 || '';
                            }
                        },
                        att2: {
                            type: 'string',
                            shortcode: attributes => {
                                return attributes.named.att2 || '';
                            },
                        },
                    },
                },
            ],
        },
        ...

I can get the content by looking at the second parameter in one of those attributes shortcode functions:

attributes: {
    att1: {
        shortcode: (attributes, data) => {
             // data.shortcode.content is the shortcode's inner content
        }
    }
}

But I don't know how to insert that content as innerBlocks in the output block. The block registration "transforms" attribute documentation is not helpful in this area.

I've tried using the transform attribute in the block definition, but that doesn't seem to work.

I am creating a block which is created when transformed from a shortcode. In other words, this:

[example att1="foo" att2="bar"]
    <p>Inner.</p>
    <p>Content.</p>
[/example]

should transform into this a myplugin/example block with inner blocks of the two p tags.

So far I've got this, which works fine to get the shortcode attributes.

(function(wp){

    wp.blocks.registerBlockType( 'myplugin/example', {
        ...

        attributes: {
            att1 {
                type: 'string',
                default: '',
            },
            att2: {
                type: 'string',
                default: '',
            },
        }, 

        transforms: {
            from: [
                {
                    type: 'shortcode',
                    tag: 'example',
                    attributes: {
                        att1: {
                            type: 'string',
                            shortcode: attributes => {
                                return attributes.named.att1 || '';
                            }
                        },
                        att2: {
                            type: 'string',
                            shortcode: attributes => {
                                return attributes.named.att2 || '';
                            },
                        },
                    },
                },
            ],
        },
        ...

I can get the content by looking at the second parameter in one of those attributes shortcode functions:

attributes: {
    att1: {
        shortcode: (attributes, data) => {
             // data.shortcode.content is the shortcode's inner content
        }
    }
}

But I don't know how to insert that content as innerBlocks in the output block. The block registration "transforms" attribute documentation is not helpful in this area.

I've tried using the transform attribute in the block definition, but that doesn't seem to work.

Share Improve this question asked Oct 3, 2019 at 16:28 JakeParisJakeParis 6633 gold badges7 silver badges22 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

There is no built-in solution to use a shortcode's inner content as a new block's innerBlocks. The best I was able to do is a two step process which first transforms a raw shortcode to the core shortcode block, then transform that into the new block. In that way I was able to use the inner content as innerBlocks.

The reason to do it that way is the "block" transform type has access to a more granular transform function. It ends up looking something like this:


     type: 'block',
     blocks: ['core/shortcode'],
     isMatch: function( {text} ) {
        return /^\[slidetoggle /.test(text);
     },
     transform: ({text}) => {

        const initialStateVal = getAttributeValue('slidetoggle', 'initialstate', text);

        const content = getInnerContent('slidetoggle', text);

        const innerBlocks = wp.blocks.rawHandler({
          HTML: content,
        });

        return wp.blocks.createBlock('example/slidetoggle', {
          initiallyClosed: initiallyClosed,
        }, innerBlocks);
     },
  },

and the getAttributeValue and getInnerContent functions look like this:

export const getAttributeValue = function(tag, att, content){
    var re = new RegExp(`\\[${tag}[^\\]]* ${att}="([^"]*)"`, 'im');
    var result = content.match(re);
    if( result != null && result.length > 0 )
        return result[1];

    re = new RegExp(`\\[${tag}[^\\]]* ${att}='([^']*)'`, 'im');
    result = content.match(re);
    if( result != null && result.length > 0 )
        return result[1];

    re = new RegExp(`\\[${tag}[^\\]]* ${att}=([^\\s]*)\\s`, 'im');
    result = content.match(re);
    if( result != null && result.length > 0 )
       return result[1];
    return false;
};

export const getInnerContent = function(tag, content, shouldAutoP=true) {
   const re = new RegExp(`\\[${tag}[^\\]]*?]([\\S\\s]*?)\\[\\/${tag}]`, 'i');
   var result = content.match(re);
   if( result == null || result.length < 1 )
      return '';

   if( shouldAutoP == true)
      result[1] = wp.autop(result[1]);

   return result[1];
};

For more details on this process, I wrote a detailed post about this.

发布评论

评论列表(0)

  1. 暂无评论