可以使用<ServerSideRender/>创建一个Carousel Gutenberg块的“可切换”预览吗?

时间:2021-03-15 作者:AmintaCode

让我们创建一个使用<InnerBlocks />:

edit.js 父组件的返回类似于:


    return(
            <div className="carousel">
                <div className="carousel__track">
                        <ul {...innerBlocksProps} className="carousel__list" />
                </div>
            </div>
          )

edit.js 返回类似以下内容的子对象:

   return(
        <li class="slide">
            <figure>
                <img src={url} data-id={id} alt={title} />
                <figcaption>
                   <h5>{caption}</h5>
                </figcaption>
            </figure>
        </li>
      )

在父级中edit.js 我会创造一个像这样的状态;const [isPreview, setIsPreview] = useState(false) 当我点击;“编辑”;按钮状态设置为false, 当我单击“a”时;预览(&Q);按钮状态设置为true.

我想当父母的国家isPreviewtrue 我可以通过<ServerSideRender />, 因此,我创建了一个服务器端渲染块,我们称之为;“myblocks/carousel预览”;我改变了edit.js 这样的家长:

 return(

         {
          !isPreview
          ?
            <div className="carousel">
                <div className="carousel__track">
                        <ul {...innerBlocksProps} className="carousel__list" />
                </div>
            </div>
          )
          :
          <>
            <ServerSideRender
            block="myblocks/carousel-preview"
            attributes={{ /* pass children here?!? */ }}
        />
          </> 

我的主要问题是:我怎样才能传递给我的<ServerSideRender /> 阻止我所在街区的孩子?

事实上,我认为<ServerSideRender /> 可能是这样的:

    
    <?php 
     function RenderCarouselServerSide($attributes, $content) {
       ob_start();
        ?>
      <div class="carousel">
        <div class="carousel__track">
          <ul class="carousel__list" />
           <?php foreach($attributes[\'children\'] as $child) :
           $url = $child[\'url\'];
           $id = $child[\'id\'];
           $caption = $child[\'caption\'];
            ?>
           <li class="slide">
            <figure>
                <img src="<?php echo $url; ?>" data-id="<?php echo $id; ?>" />
                <figcaption>
                   <h5>"<?php echo $caption; ?>"</h5>
                </figcaption>
            </figure>
          </li>
         </ul>
          <?php endforeach; ?>

          </div>
      </div>

     <?php
        return ob_get_clean();
    }
但如何让孩子们$attributes?

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

我的主要问题是:我怎样才能传递给我的<ServerSideRender /> 阻止我街区的孩子们?

实际上,你可能不需要使用ServerSideRender..

如果您只想查看来自save() 函数,然后您可以简单地使用getSaveElement() 获取该输出或save函数返回的元素。

下面是一个示例,我使用useBlockProps 引入挂钩block API version 2: (these are all for the main/parent block)

我使用的变量:

// Used in the \'edit\' and \'save\' functions.
const { useBlockProps, InnerBlocks } = wp.blockEditor;

// Used in the \'edit\' function.
const { useState } = wp.element;
const { Button } = wp.components;

// Used in the preview function.
const { select } = wp.data;
const { getSaveElement } = wp.blocks;

const edit = ( { clientId } ) => {
    const blockProps = useBlockProps();

    const [ isPreview, setIsPreview ] = useState( false );
    const setPreviewMode = () => setIsPreview( ! isPreview );

    const innerBlocksProps = { /* your code */ };

    return (
        <div { ...blockProps }>
            { isPreview ? (
                <PreviewBlock
                    clientId={ clientId }
                />
            ) : (
                <div className="carousel">
                    <div className="carousel__track">
                        <ul { ...innerBlocksProps } className="carousel__list">
                            <InnerBlocks allowedBlocks={ [ \'myblocks/carousel-child\' ] } />
                        </ul>
                    </div>
                </div>
            ) }
            <Button onClick={ setPreviewMode }>{ isPreview ? \'Close Preview\' : \'Preview\' }</Button>
        </div>
    );
};

const save = () => {
    const blockProps = useBlockProps.save( { className: \'carousel\' } );

    const innerBlocksProps = { /* your code */ };

    return (
        <div { ...blockProps }>
            <div className="carousel__track">
                <ul { ...innerBlocksProps } className="carousel__list">
                    <InnerBlocks.Content />
                </ul>
            </div>
        </div>
    );
};
和我的预览功能/组件:

function PreviewBlock( { clientId } ) {
    const { getBlock } = select( \'core/block-editor\' );

    const block = getBlock( clientId );

    return getSaveElement( \'myblocks/carousel\', block.attributes, block.innerBlocks );
}
ServerSideRender, 尽管如此:或者如果需要,您可以使用getBlocks() 要检索内部/子块,请获取每个子块的属性,并在attributes 的属性ServerSideRender 要素

因此,根据上面的代码,我只需要做以下两个更改:

在我使用的变量部分中,替换const { getSaveElement } = wp.blocks; 具有const ServerSideRender = wp.serverSideRender;.

然后将预览功能更改为:

function PreviewBlock( { clientId } ) {
    const { getBlocks } = select( \'core/block-editor\' );

    // Get the attributes of the inner/child blocks.
    const blocks = getBlocks( clientId ).map( block => block.attributes );

    return (
        <ServerSideRender
            block="myblocks/carousel-preview"
            attributes={ { children: blocks } }
            httpMethod="POST"
        />
    );
}
请注意httpMethod (HTTP请求方法)不必设置为POST,但POST将允许更大的attributes对象。

请记住,您必须注册以上内容children PHP中的属性register_block_type()). 例如。

Note: 属性名称不必为children. 你可以用你喜欢的任何其他名字。但请确保名称与上面预览函数中使用的名称匹配。

register_block_type( \'myblocks/carousel-preview\', array(
    \'apiVersion\'      => 2,
    \'render_callback\' => \'RenderCarouselServerSide\',
    \'attributes\'      => array(
        \'children\' => array(
            \'type\'    => \'array\',
            \'default\' => array(),
        ),
    ),
) );
所以我希望这会有帮助,你可能想检查我的答案here 它将块内容而不是内部块属性发送到服务器端渲染器。

相关推荐