WordPress的Gutenberg:前端的React组件

isk*_*taa 1 wordpress reactjs wordpress-gutenberg gutenberg-blocks

古腾堡仍然很新,但我仍然希望有人遇到此问题并找到解决方案。

我使用了create-guten-block来创建一个项目并创建一个测试块。我遇到的问题是,当我尝试使用React组件修改前端的状态时,什么都没有发生。组件可以通过save()很好地加载,但是当您尝试执行一些简单的操作(如切换列表)时,前端仍然无法响应状态更改。我还要注意,create-guten-block不会加载任何前端JS,因此我交换了已编译的javascript以加载到前端,但仍然无法使其正常工作。

这是我从Codecademy提取的一些代码,作为一个简单的示例进行测试。选择名称时,它将更改sibling.js中的文本以显示名称。该代码在create-react-app中可以正常工作,但作为Gutenberg中的块,在前端没有任何作用:

block.js

import { Parent } from './parent';

// More code here 

save: function( props ) {
    return (
          <div>
              <Parent />
          </div>
     );
 },
Run Code Online (Sandbox Code Playgroud)

parent.js

import React from 'react';
import { Child } from './child';
import { Sibling } from './sibling';

export class Parent extends React.Component {
    constructor(props) {
        super(props);

        this.state = { name: 'Frarthur' };

        this.changeName = this.changeName.bind(this);
    }

    changeName(newName) {
        this.setState({
        name: newName
        });
    }

    render() {
        return (
        <div>
            <Child onChange={this.changeName} />
            <Sibling name={this.state.name} />
        </div>
        );
    }
};
Run Code Online (Sandbox Code Playgroud)

child.js

import React from 'react';

export class Child extends React.Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
        const name = e.target.value;
        this.props.onChange(name);
    }

    render() {
        return (
        <div>
            <select
            id="great-names"
            onChange={this.handleChange}>

                <option value="Frarthur">Frarthur</option>
                <option value="Gromulus">Gromulus</option>
                <option value="Thinkpiece">Thinkpiece</option>
            </select>
        </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

兄弟姐妹

import React from 'react';

export class Sibling extends React.Component {
    render() {
        const name = this.props.name;
        return (
        <div>
            <h1>Hey, my name is {name}!</h1>
            <h2>Don't you think {name} is the prettiest name ever?</h2>
            <h2>Sure am glad that my parents picked {name}!</h2>
        </div>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

Bes*_*sey 8

据我了解,古腾堡仅支持编辑器方面的交互性。是的,您在 React 中定义了视图端,但该视图在保存帖子时呈现为静态标记,然后仅将此静态标记传递给客户端(读者)。

好处是你可以免费获得“服务器端渲染”,并且你的客户端不需要 React 来查看帖子。缺点是如果你想做客户端交互,它超出了古腾堡的范围,你必须找到自己的方法。


Snn*_*Snn 6

古腾堡(Gutenberg)很棒,但是不能在文档中说同样的话。就像其他任何Wordpress文档一样,它过于冗长,组织混乱和健谈。我认为这与领土和目标消费者有关。

我花了一些时间并且在手册上花了一些时间来理解什么是块。资源稀缺,人们通常将块与它们在编辑器中的屏幕视觉表示混淆。

话虽如此,让我们从古腾堡的块开始。古腾堡块是这样的优美的短代码:

<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->
Run Code Online (Sandbox Code Playgroud)

这些短代码由编辑器呈现为react组件,以进行可视化表示。

记住这里的这样的短代码,[gallery id="123" size="medium"]可以通过tinymce插件将其转换为可视化表示,您将在编辑器窗口中看到功能齐全的库。想法是一样的,只是这次古腾堡(Gutenberg)编辑器将略有不同的短代码呈现为视觉表示。

现在,由于WordPress文档也将这些视觉表示作为块来处理,因此产生了混乱。但是整个渲染-序列化-解析-重新渲染周期的真相是其中之一,那就是所谓的“优美的短代码”,其余的是这些短代码采用的不同形式和表示形式。说,在编辑器上下文中,它是一个呈现的react组件,在前端只是普通的html。

edit函数的return元素将确定块在编辑器窗口中的显示方式:

<!-- language: lang-js -->
registerBlockType(«NAMESPACE/BLOCK_NAME», {
    edit: function(props){
        // Should return a react element
    }
})
Run Code Online (Sandbox Code Playgroud)

了解块的生命周期以更好地理解它们至关重要。让我们从头开始:

当您在组件面板中单击一个块图标时,将返回save功能并序列化并插入到页面中。

<!-- language: lang-js -->
registerBlockType("NAMESPACE/BLOCK_NAME", {
    save: function(props){
       // Should return a react element
    }
})
Run Code Online (Sandbox Code Playgroud)

save函数返回一个反应元件中,通过反应该元素将被渲染和序列由块串行并插入到后的内容作为。您可以检查serializer.jsReact元素如何序列化到块1中

<!-- wp:image -->
<figure class="wp-block-image"><img src="source.jpg" alt="" /></figure>
<!-- /wp:image -->
Run Code Online (Sandbox Code Playgroud)

如果是动态块,则save函数将返回null,因此将没有内容。块看起来像这样:

<!-- wp:latest-posts {"postsToShow":4,"displayPostDate":true} /-->
Run Code Online (Sandbox Code Playgroud)

注意自我结束评论:

块语法中,第一个称为静态块(_Block_Balanced_),第二个称为动态块(_Block_Void_)。

重要的是要注意,静态块包含渲染的内容和属性的对象。对于动态块,render_callbackregister_block_type在块注册期间提供其功能。

因此,在the_content被请求时,服务器会在响应请求之前获取the_content并通过几个过滤器

在此阶段中,将从静态块中剥离属性,并返回内容,因为静态块本身已具有其内容。对于动态块,将调用render_callback并将其返回值作为块内容返回。这就是文档中完全同构3的含义。您可以render_block在Wordpress核心中签出功能。

当您通过gutenberg的视觉元素编辑该图块时,该图块将重新进行重新序列化过程,并根据您所做的更改将新的视觉表示形式绘制到页面上。

<!-- wp:paragraph {"key": "value"} -->
<p>Welcome to the world of blocks.</p>
<!-- /wp:paragraph -->
Run Code Online (Sandbox Code Playgroud)

单击发布按钮后,如文档所述,此序列化数据或行数据将保存到数据库中。

假设您保存后关闭了页面。下次打开它时,已保存的块将由块解析器解析,并且可视化表示将绘制到页面上。您可以看一下解析器2

在解析期间,将针对该save功能验证块标记。如果save在两次编辑之间更改了函数的返回值,则先前保存的块标记将无效或不建议使用。您可以通过在中的块设置中提供升级路径来更新不赞成使用的代码registerBlockType。但是,您edit无需更改即可更改该功能,因为它控制块在编辑器屏幕上的显示方式。

升级路径只是具有功能和属性的对象的数组。该数组上的每个元素将根据优先级检查已弃用的块,如果块与新版本兼容,则将迁移该块;否则,将返回旧版本。

现在来问您的问题,当请求前端服务器上的页面时,将向您发送格式完整的html。因此,在前面,您得到的是静态html,而不是react元素。

因此,实际上,save功能与前端无关,除了创建包裹在块注释中的静态html之外<!-- wp:image --><!-- /wp:image -->,这是在编辑内容时发生的。the_content在前端服务时,它永远不会运行或查询。

为了增加交互性,您必须像在Gutenberg之前一样专门针对前端编写代码。

the_content通过使用更多工具和选项按钮(在更新按钮旁边的垂直省略号)切换到编辑器窗口中的代码编辑器,可以以纯文本形式查看。

从前端角度来看,在创建时,是使用tinymce编辑器还是Gutenberg编辑器还是使用普通html都没有什么区别the_content

enqueue_block_assets注册块时,由您决定是否排入另一个javascript文件或使用通过其排入的文件。

要使用React,您必须使用ReactDOM将组件安装到文档上。不错的是,Wordpess已经在全局空间中提供了React和ReactDOM,但是您在排队脚本时需要指出依赖性。