简体   繁体   English

如何在古腾堡中使用序列化数据?

[英]How can I use serialized data in Gutenberg?

I am trying to create a Sidebar plugin that stores post meta to be used on the front end.我正在尝试创建一个侧边栏插件,用于存储要在前端使用的帖子元数据。 Without getting into the unnecessary details, I need to store all the data as 1 meta entry instead of many rows per post .在不涉及不必要的细节的情况下,我需要将所有数据存储为 1 个元条目,而不是每个帖子的许多行 Here is what I have so far:这是我到目前为止所拥有的:

// ds-jars.js

const pluginContent = (props) => {

    const productData = () => {
        const categoryId = createElement( PanelRow, null, 
            createElement(TextControl, {
                label: "Category Name",
                value: props.category_id,
                onChange: (content) => {
                    props.set_category_id(content)
                },
            })
        )
        const serialId = createElement( PanelRow, null, 
            createElement( TextControl, {
                label: "Serial Number",
                value: props.serial_id,
                onChange: (content) => { 
                    props.set_serial_id(content)
                }
            })
        )
        const productId = createElement( PanelRow, null, 
            createElement( TextControl, {
                label: "Product ID",
                value: props.product_id,
                onChange: (content) => { 
                    props.set_product_id(content)
                }
            })
        )

        return createElement(PluginDocumentSettingPanel, {
            title: "Product Data",
            name: "ds-jars-productdata",
            icon: 'none',
        }, categoryId, serialId, productId
        )
    }

    return productData()
}

const selectData = (select) => {
    return { 
        category_id:        select("core/editor").getEditedPostAttribute("meta")["category_id"],
        serial_id:          select("core/editor").getEditedPostAttribute("meta")["serial_id"],
        product_id:         select("core/editor").getEditedPostAttribute("meta")["product_id"],
        name:               select("core/editor").getEditedPostAttribute("meta")["name"],
        quantity:           select("core/editor").getEditedPostAttribute("meta")["quantity"],
        color:              select("core/editor").getEditedPostAttribute("meta")["color"],
        height:             select("core/editor").getEditedPostAttribute("meta")["height"],
        width:              select("core/editor").getEditedPostAttribute("meta")["width"],
        depth:              select("core/editor").getEditedPostAttribute("meta")["depth"],
        pattern:            select("core/editor").getEditedPostAttribute("meta")["pattern"],
        date_made:          select("core/editor").getEditedPostAttribute("meta")["date_made"],
        date_updated:       select("core/editor").getEditedPostAttribute("meta")["date_updated"],
        date_expired:       select("core/editor").getEditedPostAttribute("meta")["date_expired"]
    }
}

const dispatchData = (dispatch) => {
    return {
        set_category_id:    (value) => {dispatch("core/editor").editPost({meta:{category_id: value} })},
        set_serial_id:      (value) => {dispatch("core/editor").editPost({meta:{serial_id: value} })},
        set_product_id:     (value) => {dispatch("core/editor").editPost({meta:{product_id: value} })},
        set_name:           (value) => {dispatch("core/editor").editPost({meta:{name: value} })},
        set_quantity:       (value) => {dispatch("core/editor").editPost({meta:{quantity: value} })},
        set_color:          (value) => {dispatch("core/editor").editPost({meta:{color: value} })},
        set_height:         (value) => {dispatch("core/editor").editPost({meta:{height: value} })},
        set_width:          (value) => {dispatch("core/editor").editPost({meta:{width: value} })},
        set_depth:          (value) => {dispatch("core/editor").editPost({meta:{depth: value} })},
        set_pattern:        (value) => {dispatch("core/editor").editPost({meta:{pattern: value} })},
        set_date_made:      (value) => {dispatch("core/editor").editPost({meta:{date_made: value} })},
        set_date_updated:   (value) => {dispatch("core/editor").editPost({meta:{date_updated: value} })},
        set_date_expired:   (value) => {dispatch("core/editor").editPost({meta:{date_expired: value} })}
    }
}

let fieldSelect = withSelect(selectData)(pluginContent)
let fieldDispatch = withDispatch(dispatchData)(fieldSelect)

registerPlugin( "ds-jars", {
    icon: 'store',
    render: fieldDispatch 
})

Obviously this works but saves each field as its own meta row entry.显然这可行,但将每个字段保存为它自己的元行条目。 According to this post: WP 5.3 Supports Object and Array Meta Types in the REST API .根据这篇文章: WP 5.3 Supports Object and Array Meta Types in the REST API I should be able to send an object to the meta field by using an array in for "show_in_rest".我应该能够通过为“show_in_rest”使用数组 in 将 object 发送到元字段。 I have been able to register the field I want properly using the following:我已经能够使用以下方法正确注册我想要的字段:

register_post_meta('', 'ds_product', 
            array(
                'type' => 'object',
                'single' => true,
                'show_in_rest' => array(
                    'schema' => array(
                        'type' => 'object',
                        'properties' => array(
                            'category_id'   => array('type' => 'string'),
                            'serial_id'     => array('type' => 'string'),
                            'product_id'    => array('type' => 'string'),
                            'name'          => array('type' => 'string'),
                            'quantity'      => array('type' => 'string'),
                            'color'         => array('type' => 'string'),
                            'height'        => array('type' => 'string'),
                            'width'         => array('type' => 'string'),
                            'depth'         => array('type' => 'string'),
                            'pattern'       => array('type' => 'string'),
                            'date_made'     => array('type' => 'string'),
                            'date_updated'  => array('type' => 'string'),
                            'date_expired'  => array('type' => 'string'),
                        )
                    )
                )
            )
        );

I am able to manually send an object through with console.log so it seems it is ready for my values to be sent to it as an object. The problem I am having is writing/reading to this meta field using the withSelect/withDispatch functions.我可以通过 console.log 手动发送一个 object,因此它似乎已准备好将我的值作为 object 发送给它。我遇到的问题是使用 withSelect/withDispatch 函数写入/读取此元字段. How can I send all my values to this meta field "ds_product" using withDispatch?如何使用 withDispatch 将所有值发送到此元字段“ds_product”? Been struggling with this for a week.已经为此苦苦挣扎了一个星期。 I have tried many things the closest I got was using我已经尝试了很多东西,我最接近的是使用

// Create prop to get data from serialized field
category_id: select("core/editor").getEditedPostAttribute("meta")["ds_product"].category_id
category_id: select("core/editor").getEditedPostAttribute("meta")["ds_product"].serial_id
...

// Update serialized field
set_category_id: (value) => {dispatch("core/editor").editPost({meta:{ds_product:{category_id: value} }})},
set_serial_id: (value) => {dispatch("core/editor").editPost({meta:{ds_product:{serial_id: value} }})},
...

Since they update one at a time the field ends up storing the previously changed value only thus wiping all other data before it.由于它们一次更新一个,因此该字段最终仅存储先前更改的值,从而擦除它之前的所有其他数据。 Any help would be hugely appreciated.任何帮助将不胜感激。 As a final note I am aware of the dangers/limitations of storing serialized data to the database but I still need it to be done this way.最后一点,我知道将序列化数据存储到数据库的危险/限制,但我仍然需要以这种方式完成。 Thanks ahead of time!提前致谢!

I came across this issue and what has worked for me is the following usage of dispatch() and saveEntityRecord .我遇到了这个问题,对我有用的是dispatch()saveEntityRecord的以下用法。

In the following example I am saving a serialized object to the wp_options table in the WP database.在下面的示例中,我将序列化的 object 保存到 WP 数据库中的wp_options表中。

// Save serialized data to wp_options.
dispatch('core').saveEntityRecord('root', 'site', {
    my_plugin_settings: {
      test_1: 'Test 1 Setting Value',
      test_2: 'Test 1 Setting Value',
    },
  }).then(() => {

  })
  .catch((error) => {
    dispatch('core/notices').createErrorNotice('Error', {
      isDismissible: true,
      type: 'snackbar',
    });
  });
});

First, you have to register the settings like you have above so it's available over the REST API.首先,您必须像上面那样注册设置,以便通过 REST API 可用。

register_setting(
        'my_plugin_settings',
        'my_plugin_settings',
        [
            'default'      => '',
            'show_in_rest' => [
                'schema' => [
                    'type'       => 'object',
                    'properties' => [
                        'test_1' => [
                            'type' => 'string',
                        ],
                        'test_2'                 => [
                            'type' => 'string',
                        ],
                    ]
                ],
            ]
        ]
    );

Then using the code in my answer above you can save the serialized value properly.然后使用上面我的答案中的代码,您可以正确保存序列化值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何在 JavaScript 中使用 PHP 函数(Gutenberg WordPress) - how can i use PHP functions (Gutenberg WordPress) inside JavaScript 如何制作一个可以将任何页面 Gutenberg 转换为 Elementor 和 Elementor 到 Gutenberg 的 Wordpress 插件 - How can I make a Wordpress plugin that can convert any page Gutenberg to Elementor and Elementor to Gutenberg 我可以保存序列化表格数据吗? - Can I save serialized form data? 如何使用Rails序列化字段中存储的数据 - How to use the data stored in a rails serialized field 如何在Gutenberg的Inspector控件中添加条件控件字段? - How can I add conditional control field in Inspector controls of Gutenberg? 在JavaScript中,如何遍历来自asmx Web服务的数据? (由JavaScriptSerializer序列化) - in JavaScript how can I loop through data from an asmx web service? (serialized by a JavaScriptSerializer) 我如何使用序列化(jQuery / Ajax)遍历表单数据 - How can I loop over form data using serialized (jQuery / Ajax) Redux 工具包:如何在 state 中存储序列化动作创建器? - Redux Toolkit: How can I store a serialized action creator in state? 如何从该序列化的字符串创建PHP数组? - How can I create a PHP array from this serialized string? JS如何将序列化的对象转换为数组? - JS How can I convert a serialized object to an Array?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM