首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wordpress Gutenberg PluginDocumentSettingPanel不使用控件吗?

Wordpress Gutenberg PluginDocumentSettingPanel不使用控件吗?
EN

Stack Overflow用户
提问于 2019-10-29 13:00:20
回答 3查看 2.3K关注 0票数 3

我希望向gutenberg文档面板中添加一个自定义元字段,并使用这位医生。对于自定义元字段,我使用了本教程。当我试图把它们组合在一起时,我就会遇到这个问题。

到目前为止,我的代码如下:

代码语言:javascript
复制
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,我解决了这个问题:)

一开始我的侧边栏看起来还不错:

但是,当我试图更改输入值时,它不会被更新(但是wp.data中的存储是更新的)。我也不能删除它。它保持在它的初始值。当我移除设置初始值的部分时,它的工作原理是应该的,但是由于我需要初始值,这对我来说不是一个选项;)

这里,当我将一个"x“添加到输入的末尾时,控制台中的一个示例日志(如上所述,输入本身中的文本不会改变)。

有人知道如何使输入字段正常工作吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-10-29 15:17:28

首先,确保安装了https://wordpress.org/plugins/gutenberg/插件,因为PluginDocumentSettingPanel还没有在核心WP中完全实现。按照这些推特,它应该是5.3版本的。

其次,您不需要wp.plugins的interval函数。它最初未定义的原因是WordPress不知道您需要先加载wp插件。来自WordPress文档

如果您想使用编辑器模块中的PlainText组件,首先要在对脚本进行队列时将wp-编辑器指定为依赖项。

其他所有模块(读脚本,如'wp-plugins')也是如此。在注册js插件脚本时,必须将'wp-plugins‘脚本添加为依赖项:

代码语言:javascript
复制
<?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是从正式WP文件中提取的。

我还建议从Css技巧中彻底阅读这个很棒的教程。它深入地介绍了只使用ESNext包设置@wordpress/脚本环境的问题。它超越了依赖项,添加了元字段等更多内容:)我希望这会有所帮助!

编辑:在测试了作者的代码之后,我发现了一些问题。首先,TextControl缺少一个结束标记。其次,我从wp数据包中添加了高阶组件,然后我使用它来“增强”TextControl,这样它就不会直接操作或读取数据,而是将逻辑抽象到它的高阶分量中。代码看起来是这样的:

代码语言:javascript
复制
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将不允许您保存它,因为它将其视为一个私有值,因此在注册该字段时需要添加额外的代码:

代码语言:javascript
复制
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技巧教程中解释的。

票数 6
EN

Stack Overflow用户

发布于 2019-12-11 02:54:30

我也遇到了同样的问题--在字段和数据库中没有更新值--经过一些研究后,我发现原因是您应该在调用'custom-fields'时将'supports'添加到register_post_type()数组中,如下所示:

代码语言:javascript
复制
register_post_type(
    'my_post_type_slug',
    array(
        ...
       'supports' => array( 'title', 'editor', 'custom-fields' ),
        ...
    )
);

在加载块编辑器时,您可以通过在wp.data.select( 'core/editor' ).getCurrentPost().meta控制台中调用JavaScript来测试它是否工作。如果post类型不添加对'custom-fields'的支持,则此调用将返回undefined;如果返回,则返回一个空数组(更确切地说,返回数据库中已有元数据的数组)。在注册post meta的说明中提到了这个行为,在古腾堡的医生里

为了确保字段已经加载,查询块编辑器内部数据结构,也称为存储。打开浏览器的控制台,执行以下代码: wp.data.select(核心/编辑器).getCurrentPost().meta; 在将register_post_meta函数添加到插件之前,这段代码返回一个空数组,因为WordPress还没有被告知要加载任何元字段。注册该字段后,相同的代码将返回一个包含已注册的元字段的对象。

票数 2
EN

Stack Overflow用户

发布于 2021-03-21 18:41:26

我最近做了一个类似的实现,并通过了大量的例子。在上述文章和这个伟大的系列由一个自动化的发展之间,我使用更新的useSelectuseDispatch自定义钩子获得了上述示例的工作版本。它确实非常相似,但使用了自定义钩子( React 16.8 )来获得稍微简洁的开发体验:

(而且,使用@wordpress/scripts,所以导入是从npm包而不是直接从wp对象导入的,但两者都能工作。)

代码语言:javascript
复制
import { __ } from '@wordpress/i18n';
import { useSelect, useDispatch } from '@wordpress/data';
import { PluginDocumentSettingPanel } from '@wordpress/edit-post';
import { TextControl } from '@wordpress/components';

const TextController = (props) => {
  const meta = useSelect(
    (select) =>
      select('core/editor').getEditedPostAttribute('meta')['_myprefix_text_metafield']
  );
  const { editPost } = useDispatch('core/editor');
  return (
    <TextControl
      label={__("Text Meta", "textdomain")}
      value={meta}
      onChange={(value) => editPost({ meta: { _myprefix_text_metafield: value } })}
    />
  );
};

const PluginDocumentSettingPanelDemo = () => {
  return (
    <PluginDocumentSettingPanel
      name="custom-panel"
      title="Custom Panel"
      className="custom-panel"
    >
      <TextController />
    </PluginDocumentSettingPanel>
  );
};

export default PluginDocumentSettingPanelDemo;

希望这能帮助其他人搜索。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58607970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档