Gutenberg - 一种块类型中的多个 InnerBlocks

Posted

技术标签:

【中文标题】Gutenberg - 一种块类型中的多个 InnerBlocks【英文标题】:Gutenberg - Multiple InnerBlocks in one block-type 【发布时间】:2018-12-06 21:59:36 【问题描述】:

我正在尝试阻止自定义列,因为古腾堡使用的 wordpress 默认值不是我需要的。

所以我查看了它的工作原理,它使用带有布局定义的 InnerBlocks 块,但是无法指定 html 标记和列的类,所以它对我来说没用。

然后我决定使用 map 循环出列,效果很好,然后我在每一列内添加了 InnerBlocks 组件以允许将其他块插入到列中,但问题是在每一列中,InnerBlocks 的内容是共享的,所以我尝试将每个 InnerBlock 和列的键属性设置为唯一,并且它们的内容仍然是共享的(不,我没有使用共享块)。

看起来古腾堡在每一列中使用了相同的 InnerBlocks 实例。

我正在尝试构建一个块类型,您可以在其中动态添加列,并在每列中添加带有一些信息的“卡片”。

为了说明我在做什么,这里是编辑功能的返回:

<section className="infonav">
            <div className="infonav__container">
                <div>
                    <button onClick=onAddBox>__('Add column', 'zmg-blocks')</button>
                </div>
                <div className="infonav__row">
                    [...new Array(columns).keys()].map((item, index) => 
                        return (
                                <div className="infonav__row__col" key="info_cols"+index>
                                    <div>
                                        <button onClick=onRemoveBox.bind(index)>
                                            __('Remove', 'zmg-blocks')
                                        </button>
                                    </div>
                                    <InnerBlocks key="info_boxes"+index/>
                                </div>
                        );
                    )
                </div>
            </div>
        </section>

谢谢

【问题讨论】:

【参考方案1】:

好像gutenberg Innerblocks只能在一个方块中使用一次

注意:一个块在编辑和保存时最多只能渲染一个 InnerBlocks 和 InnerBlocks.Content 元素。要创建嵌套块的不同排列,请创建一个单独的块类型,该类型呈现其自己的 InnerBlocks 并指定为唯一的 allowedBlocks 类型。

来源:https://github.com/WordPress/gutenberg/tree/master/packages/block-editor/src/components/inner-blocks

您需要创建另一个自定义块(仅用于列)以及此块,该块也在其中使用 Innerblock,以便其他块可以嵌套在其中。 您可以使用 allowedBlocks 仅允许此块中的自定义列

【讨论】:

InnerBlocks 现在是 block-editor 包的一部分,而不是 editor 包的一部分。因此,正确的 URL 是github.com/WordPress/gutenberg/tree/master/packages/…。虽然不建议链接到master URL,因为它们可以更改。 如何将自定义块包含在主块中?如果您能说明您的解释,那将非常非常有帮助:)【参考方案2】:

如果您打算通过'block-editor'中的InnerBlock添加多个gutenberg块,如下所示,还没有办法添加多个块:

const BLOCK_TEMPLATE = [
  ['image-slider',  width: 800, height: 400 ],
  ['menu'],
];

registerBlockType('peregrine/inner-block-demo', 

  title: 'Inner Block Demo',

  edit( className ) 
    return (
      <div className=className>
        <InnerBlocks
          template=BLOCK_TEMPLATE
          templateLock="all"
        />
      </div>
    );
  ,

  save() 
    return (
      <div>
        <InnerBlocks.Content />
      </div>
    );
  ,
);

多个内部块的复杂性似乎不值得 努力,一般来说,它要么暗示一个应该是 分解为多个更简单的块,或具有块属性 (不是儿童)。让我们知道上述建议如何为您服务,并 我们可以重温。

您可以在此处关注讨论:https://github.com/WordPress/gutenberg/issues/6808

但是,您的代码看起来更像是添加内部元素,这是可能的。

所以为了进一步澄清,您提供给 registerBlockType 函数的不是块。古腾堡会阻止优雅的简码,如下所示:

<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg"  /></figure>
<!-- /wp:image -->

或者这个:

<!-- wp:latest-posts "postsToShow":4,"displayPostDate":true /-->

第一个被称为静态块,因为它有它的内容。第二个称为动态块,因为它是自闭块并且没有内容。内容将从您注册块时提供的 php 回调中检索。

Gutenberg 使用 React 将块的可视化表示打印到编辑器屏幕上。设置对象上的编辑方法应该返回一个反应元素,这个元素将用于在编辑器中为块生成可视化表示。 save 方法也应该返回 react 元素,但是这个元素会被渲染成静态 html 并保存到数据库中:&lt;figure class="wp-block-image"&gt;&lt;img src="source.jpg" alt="" /&gt;&lt;/figure&gt;。现在,动态块没有返回元素,因为它们返回 null,因此它们中没有内容,这就是它们自闭的原因。

当服务器响应请求时,它会获取存储在数据库中的内容,并通过解析器运行它来查看它是静态块还是动态块。如果块是静态的,它本身就有它的内容,所以内容将被返回。如果是动态的,则会调用注册的回调函数并返回其返回值。

现在,要回答您的问题,保存和编辑功能应该返回反应元素。 react 元素必须有单个根元素,但内部元素可以是任何常规 html,例如:

<div>
  <h1>Hello world</h1>
  <p>This is a sentence</p>
</div>

这是出于性能原因。 DOM 操作是昂贵的,这就是为什么它有一个进入 DOM 的入口点。这就是为什么它非常快。然后它有自己的 DOM,一整棵树驻留在内存中。当发生更改时,React 将遍历其 DOM 树并仅渲染更改的分支,不会对每一个微小的更改都绘制整个树。

这里的重要细节是上面的代码看起来像 html 但它不是,它是 jsx。 React 不能直接渲染 html。 Jsx 会被 babel 之类的转译器转译成 react 元素。

React 上还有 createElement 方法,可用于创建反应元素。 wp 重新导出此方法。

您可以在另一个中渲染一个反应元素。如果不学习反应,您将永远无法完全掌握积木的力量或潜力。 React 库并没有那么大。一旦你掌握了它背后的想法,你就可以在一两周内学会它,从而提高工作效率。

【讨论】:

谢谢你很好的解释,我熟悉我在其中开发的反应,但在纯粹的反应中,这段代码可以正常工作(因为我做了很多转发器/收集表格),但现在我了解如果古腾堡如何使用反应,我需要为 infonav__row__col 创建一个单独的组件

以上是关于Gutenberg - 一种块类型中的多个 InnerBlocks的主要内容,如果未能解决你的问题,请参考以下文章

php 禁用Gutenberg用于特定的帖子类型。

php Gutenberg Block Editor允许块类型

php 自定义帖子类型注册(W / Gutenberg支持)

WordPress - 如何阻止 Gutenberg Block 触发多个 GET 请求?

尝试为 Gutenberg 创建 ACF 块时出现“不存在块类型”

Gutenberg Blocks:使用 `register_block_type_from_metadata()` 注册多个块会在控制台中引发错误