在块变换中,如何插入内部块?

时间:2019-10-03 作者:JakeParis

我正在创建一个从短代码转换而来的块。换句话说,这:

[example att1="foo" att2="bar"]
    <p>Inner.</p>
    <p>Content.</p>
[/example]
应转换为myplugin/example 两个p标记的内部块。

到目前为止,我已经得到了这个,它可以很好地获得短代码属性。

(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 || \'\';
                            },
                        },
                    },
                },
            ],
        },
        ...
我可以通过查看其中一个属性shortcode函数中的第二个参数来获取内容:

attributes: {
    att1: {
        shortcode: (attributes, data) => {
             // data.shortcode.content is the shortcode\'s inner content
        }
    }
}
但我不知道如何在输出块中插入作为内部块的内容。这个block registration "transforms" attribute documentation 在这方面没有帮助。

我试过使用transform 属性,但这似乎不起作用。

1 个回复
SO网友:JakeParis

没有将短代码的内部内容用作新块的内置解决方案innerBlocks. 我所能做的最好的事情是两步过程,首先将原始短代码转换为核心短代码块,然后将其转换为新块。这样,我就可以将内部内容用作内部块。

这样做的原因是“块”变换类型可以访问更细粒度的变换函数。它最终看起来像这样:


     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);
     },
  },
以及getAttributeValuegetInnerContent 函数如下所示:

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];
};
关于这个过程的更多细节,我写了detailed post about this.

相关推荐