Wie kann ich serialisierte Daten in Gutenberg verwenden?

Lesezeit: 5 Minuten

Benutzer-Avatar
noch nicht_genug

Ich versuche, ein Sidebar-Plugin zu erstellen, das Post-Meta speichert, das am Frontend verwendet werden soll. Ohne auf unnötige Details einzugehen, Ich muss alle Daten als 1 Meta-Eintrag speichern, anstatt viele Zeilen pro Post. Hier ist, was ich bisher habe:

// 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 
})

Offensichtlich funktioniert dies, speichert aber jedes Feld als eigenen Metazeileneintrag. Laut diesem Beitrag: WP 5.3 unterstützt Objekt- und Array-Metatypen in der REST-API. Ich sollte in der Lage sein, ein Objekt an das Metafeld zu senden, indem ich ein Array für “show_in_rest” verwende. Ich konnte das gewünschte Feld wie folgt richtig registrieren:

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'),
                        )
                    )
                )
            )
        );

Ich kann ein Objekt manuell mit console.log durchsenden, sodass es anscheinend bereit ist, meine Werte als Objekt daran zu senden. Das Problem, das ich habe, ist das Schreiben/Lesen in dieses Metafeld mit den Funktionen withSelect/withDispatch. Wie kann ich alle meine Werte mit withDispatch an dieses Metafeld “ds_product” senden? Habe seit einer Woche damit zu kämpfen. Ich habe viele Dinge ausprobiert, die mir am nächsten kamen, war die Verwendung

// 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} }})},
...

Da sie einzeln aktualisiert werden, speichert das Feld am Ende nur den zuvor geänderten Wert, wodurch alle anderen Daten davor gelöscht werden. Jede Hilfe wäre sehr willkommen. Als letzte Anmerkung bin ich mir der Gefahren/Einschränkungen beim Speichern von serialisierten Daten in der Datenbank bewusst, aber ich muss es trotzdem auf diese Weise tun. Vielen Dank im Voraus!

Benutzer-Avatar
Devin Walker

Ich bin auf dieses Problem gestoßen und was für mich funktioniert hat, ist die folgende Verwendung von dispatch() und saveEntityRecord.

Im folgenden Beispiel speichere ich ein serialisiertes Objekt im wp_options Tabelle in der WP-Datenbank.

// 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',
    });
  });
});

Zuerst müssen Sie die Einstellungen wie oben beschrieben registrieren, damit sie über die REST-API verfügbar sind.

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

Dann können Sie mit dem Code in meiner obigen Antwort den serialisierten Wert ordnungsgemäß speichern.

1335490cookie-checkWie kann ich serialisierte Daten in Gutenberg verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy