如何正确弃用 Gutenberg 块

Posted

技术标签:

【中文标题】如何正确弃用 Gutenberg 块【英文标题】:How do I properly deprecate Gutenberg block 【发布时间】:2021-08-18 17:18:36 【问题描述】:

我有一个自定义 Gutenberg 块 (https://pastebin.com/bV2k5Ekc),我在其中显示文本、链接和图像。我想更改它,而不是将图像 URL 保存为容器的背景图像,而是使用 img 标记。不幸的是 - 我无法正确创建弃用 - 我无法在弃用中分配属性参数:

从这里:

    const 
      attributes: 
        mediaURL,
        boxTitle,
        boxDescription,
        linkText,
        linkHref,
        linkTitle
      ,
      className,
     = props;

    let boxClass = 'cta-box';
    let contentDescription = '';

    if (boxDescription.length) 
      boxClass += ' cta-box-description';
      contentDescription = (
        <p>
          boxDescription
        </p>
      )
    

    return (
      <div className=`cta-block-box $className`>
        <a
          className="cta-box-link"
          href=linkHref
          style= backgroundImage: "url(" + mediaURL + ")" 
          rel="noopener noreferrer"
        >
          <div className=boxClass>
            <h3>
              boxTitle
            </h3>
            contentDescription
            <span className="arrow">linkText ? linkText : linkTitle</span>
          </div>
        </a>
      </div>
    );
  ,

对此(我只更改 return 语句中的内容):

return (
      <div className=`cta-block-box $className`>
        <a
          className="cta-box-link"
          rel="noopener noreferrer"
        >
          <img className="cta-box-image" src=linkHref />
          <div className=boxClass>
            <h3>
              boxTitle
            </h3>
            contentDescription
            <span className="arrow">linkText ? linkText : linkTitle</span>
          </div>
        </a>
      </div>
    );

这当然破坏了古腾堡元素。所以我在博客中添加了一个弃用,尽可能遵循官方 Wordpress 文档:

deprecated: [
    
      attributes: ...this.attributes,
      save: (props) => 
        const 
          attributes: 
            mediaURL,
            boxTitle,
            boxDescription,
            linkText,
            linkHref,
            linkTitle
          ,
          className,
         = props;
        console.log('dep');
        console.log(props);

        let boxClass = 'cta-box';
        let contentDescription = '';

        if (boxDescription.length) 
          boxClass += ' cta-box-description';
          contentDescription = (
            <p>
              boxDescription
            </p>
          )
        

        return (
          <div className=`cta-block-box $className`>
            <a
              className="cta-box-link"
              style= backgroundImage: "url(" + mediaURL + ")" 
              rel="noopener noreferrer"
            >
              <div className=boxClass>
                <h3>
                  boxTitle
                </h3>
                contentDescription
                <span className="arrow">linkText ? linkText : linkTitle</span>
              </div>
            </a>
          </div>
        );
      ,
    
  ],

在此之后编辑器页面崩溃,并且我在控制台中收到错误消息,该属性未定义(在脚本文件中显示不正确的行)。这是“之后”的脚本内容 (https://pastebin.com/dVdLMx7N)。

react-dom.min.js?ver=16.13.1:125 ReferenceError: attributes is not defined
    at save (cta-box2.js?f66a:242)
    at Wt (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
    at Qt (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
    at block-editor.min.js?ver=4378547cec8f5157a02ead3dfc5c65b2:12
    at hooks.min.js?ver=50e23bed88bcb9e6e14023e9961698c1:2
    at $r (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
    at blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3
    at Ur (blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3)
    at blocks.min.js?ver=9ed25ffa009c799f99a4340915b6dc6a:3
    at Array.reduce (<anonymous>)

任何帮助将不胜感激!我怀疑我遗漏了一些小细节,但到目前为止我还没有找到它。并且无法在网络上找到足够的相关信息。

提前致谢!

【问题讨论】:

弃用函数的诀窍是你基本上完全复制你之前在save函数中拥有的东西。与属性相同。它们需要完全与之前版本的块一样。 @Phil,这就是我通常所做的。让我感到困惑的是属性没有传递给弃用,或者我无法在那里初始化它们。我没有更改任何属性 - 我使用相同的值,只是更改它们的解释方式。 【参考方案1】:

your "after" script有两个问题:

    属性不匹配(this 实际上是window 对象):attributes: ...this.attributes(见第 212 行)。

    所以你在第 24 行与 attributes 属性一起使用的东西,也应该与第 212 行的相同属性一起使用。(因为你只更改了输出,所以块属性保持不变)

    save 输出/标记也不匹配 — 在“之前”脚本中,您有 href=linkHref,但在“之后”脚本的 deprecated 属性中save 输出没有 href。 (see this diff)

所以请确保属性和save 输出与旧/“之前”脚本中的匹配,以下是您的代码的外观,但请注意,我只包含了需要修复的主要部分:

// Define the attributes and use it with the root "attributes" property and
// the one in the "deprecated" property.
const blockAttributes = 
  mediaID: 
    type: 'number'
  ,
  mediaURL: 
    type: 'string'
  ,
  boxTitle: 
    type: 'string',
    default: ''
  ,
  // ... the rest of the attributes here.
;

registerBlockType('hswp/test-box', 
  title: __('Test Box', 'modula'),
  // ... your code.
  attributes: blockAttributes,
  // ... your code.
  deprecated: [
    
      attributes: blockAttributes,
      save: (props) => 
        // ... your code.

        return (
          <div className=`cta-block-box $className`>
            <a
              className="cta-box-link"
              href=linkHref
              style= backgroundImage: "url(" + mediaURL + ")" 
              rel="noopener noreferrer"
            >
              ... your code.
            </a>
          </div>
        );
      ,
    
  ],
);

另外,请注意PlainText component 没有(截至撰写时)有一个名为tagName 的属性。

【讨论】:

谢谢!缺少href主要是尝试重现该问题的问题,因为我以另一种方式解决了原始问题(交货时间紧迫)。我的方法的主要问题是我没有想到我可以在 registerBlockType 之外初始化属性,因此在获取它们时遇到了问题。使用您提出的解决方案,该块可以工作,我成功地使用旧版本创建了一个块,更改了代码,当我再次保存该块时 - 它工作了! pastebin.com/MvdGWx3P

以上是关于如何正确弃用 Gutenberg 块的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Wordpress 中列出和重新排列或操作 Gutenberg 块类别

如何以编程方式在主题中使用 Wordpress Gutenberg 块?

javascript 有关如何在Gutenberg中为块使用自定义SVG图标的示例

为Gutenberg自定义块添加内置调色板

在 Gutenberg 自定义横幅块中使用页面标题

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