reactjs - Wordpress Gutenberg PluginDocumentSettingPanel 不适用于控件?

标签 reactjs wordpress wordpress-gutenberg

我想向古腾堡文档面板添加自定义元字段并使用 this doc .对于我使用的自定义元字段 this tutorial . 尝试将它们放在一起时出现了问题。

到目前为止,这是我的代码:

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { InspectorControls } = wp.editor;
const { registerPlugin } = wp.plugins
const { PluginDocumentSettingPanel } = wp.editPost
const { PanelBody, PanelRow, TextControl } = wp.components

const PluginDocumentSettingPanelDemo = () => (
    <PluginDocumentSettingPanel
        name="custom-panel"
        title="Custom Panel"
        className="custom-panel"
    >
        <TextControl 
          value={wp.data.select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']}
          label={ "Text Meta" }
          onChange={(value) => wp.data.dispatch('core/editor').editPost({meta: {_myprefix_text_metafield: value}})}
        />
    </PluginDocumentSettingPanel>
)
registerPlugin('plugin-document-setting-panel-demo', {
    render: PluginDocumentSettingPanelDemo
})

编辑:感谢 Ivan,我解决了这个附带问题 :)


我的侧边栏起初看起来不错:

enter image description here

但是当我尝试更改输入值时,它不会更新(但 wp.data 中的存储是)。我也删不掉它保持在它的初始值。当我删除我设置初始值的部分时,它的工作方式应该是这样,但是由于我需要初始值,所以这不是我的选择;)

这里是我在输入末尾添加“x”时来自控制台的示例日志(如上所述,输入本身中的文本不会改变)

enter image description here

有人知道如何让输入框正常工作吗?

最佳答案

首先,确保您拥有 https://wordpress.org/plugins/gutenberg/已安装插件,因为 PluginDocumentSettingPanel 尚未在核心 WP 中完全实现。根据 these tweets 应该是 5.3 版本.

其次,您不需要 wp.plugins 的区间函数。最初未定义的原因是 WordPress 不知道您需要先加载 wp-plugins。来自 WordPress documentation

If you wanted to use the PlainText component from the editor module, first you would specify wp-editor as a dependency when you enqueue your script

这同样适用于所有其他模块(读取脚本,如“wp-plugins”)。 注册 js 插件脚本时,您必须添加“wp-plugins”脚本作为依赖项:

<?php

/*
Plugin Name: Sidebar plugin
*/

function sidebar_plugin_register() {
    wp_register_script(
        'plugin-sidebar-js',
        plugins_url( 'plugin-sidebar.js', __FILE__ ),
        array( 'wp-plugins', 'wp-edit-post', 'wp-element' ) // <== the dependencies array is important!
    );
}
add_action( 'init', 'sidebar_plugin_register' );

function sidebar_plugin_script_enqueue() {
    wp_enqueue_script( 'plugin-sidebar-js' );
}
add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

上面的PHP取自official WP documentation .

我还建议您仔细阅读 awesome tutorial来自 CSS 技巧。它深入介绍了仅使用 @wordpress/scripts 设置 ESNext 环境。包裹。它检查了依赖项,添加了元字段等等 :) 我希望这会有所帮助!

---------------- 初始答案到此结束 ---------------

编辑:在测试作者的代码后,我发现了几个问题。首先,TextControl 缺少一个结束标记。其次,我从 wp-data 包中添加了高阶组件,然后我用它来“增强”TextControl,这样它就不会直接操作或读取数据,而是将逻辑抽象到它的 higher order components 中。 .代码如下所示:

const { __ } = wp.i18n;
const { registerPlugin } = wp.plugins;
const { PluginDocumentSettingPanel } = wp.editPost;
const { TextControl } = wp.components;
const { withSelect, withDispatch, dispatch, select } = wp.data;
// All the necessary code is pulled from the wp global variable,
// so you don't have to install anything
// import { withSelect, withDispatch, dispatch, select } from "@wordpress/data";
// !!! You should install all the packages locally,
// so your editor could access the files so you could
// look up the functions and classes directly. 
// It will not add to the final bundle if you
// run it through wp-scripts. If not, you can
// still use the wp global variable, like you have done so far.



let TextController = props => (
    <TextControl
        value={props.text_metafield}
        label={__("Text Meta", "textdomain")}
        onChange={(value) => props.onMetaFieldChange(value)}
    />
);

TextController = withSelect(
    (select) => {
        return {
            text_metafield: select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
        }
    }
)(TextController);

TextController = withDispatch(
    (dispatch) => {
        return {
            onMetaFieldChange: (value) => {
                dispatch('core/editor').editPost({ meta: { _myprefix_text_metafield: value } })
            }
        }
    }
)(TextController);

const PluginDocumentSettingPanelDemo = () => {
    // Check if a value has been set
    // This is for editing a post, because you don't want to override it everytime
    if (!select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']) {
        // Set initial value
        dispatch('core/editor').editPost({ meta: { _myprefix_text_metafield: 'Your custom value' } });
    }
    return (
        <PluginDocumentSettingPanel
            name="custom-panel"
            title="Custom Panel"
            className="custom-panel"
        >
            <TextController />
        </PluginDocumentSettingPanel>
    )
};
registerPlugin('plugin-document-setting-panel-demo', {
    render: PluginDocumentSettingPanelDemo
})

由于元字段是用下划线作为名称中的第一个符号注册的,因此WordPress不允许您保存它,因为它会将其视为私有(private)值,因此您需要在注册字段时添加额外的代码:

function myprefix_register_meta()
{
    register_post_meta('post', '_myprefix_text_metafield', array(
        'show_in_rest' => true,
        'type' => 'string',
        'single' => true,
        'sanitize_callback' => 'sanitize_text_field',
        'auth_callback' => function () {
            return current_user_can('edit_posts');
        }
    ));
}
add_action('init', 'myprefix_register_meta');

同样,所有这些都在 Css tricks tutorial 中进行了解释。 .

关于reactjs - Wordpress Gutenberg PluginDocumentSettingPanel 不适用于控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58607970/

相关文章:

php - 联系表格 7 电话号码验证

php - 从后端产品页面隐藏特色复选框设置

reactjs - 在 block 编辑器中获取对 BlockListBlock 的引用

html - WordPress 之外的古腾堡编辑器

reactjs - 修改状态对象而不调用setState,而是调用对象方法

javascript - react : how to check Proptypes with function and shape?

php - 带有当前页面 ID 的短代码

wordpress-gutenberg - 获取PHP中的可重用 block

javascript - 为什么 JS/React 比 WebAssembly/Rust 快得多?

javascript - 如何在客户端 reactjs 上使用基于角色的身份验证?