从Gutenberg块读取并保存WP po​​st元字段数据

问题描述

我以this article中的代码为例。 可以读取数据,但不能保存。

代码

const { Component,Fragment } = wp.element;

const {
  RichText,InspectorControls,PanelColorSettings,AlignmentToolbar,BlockControls,} = wp.editor;

const { Button,PanelBody,SelectControl,TextControl } = wp.components;

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;

const { withSelect,withdispatch } = wp.data;

class Inspector extends Component {
  constructor(props) {
    super(...arguments);
  }
  render() {
    const backgroundColors = [
      { color: "#525252",name: "Черный" },{ color: "#872d2d",name: "Акцентный красный" },{ color: "#e49312",name: "Акцентный желтый" },{ color: "#bab3a6",name: "Акцентный кремовый" },];

    const fontSizeOptions = [
      { value: "14px",label: __("14px") },{ value: "16px",label: __("16px") },{ value: "18px",label: __("18px") },{ value: "22px",label: __("22px") },{ value: "28px",label: __("28px") },];

    const paddingTopOptions = [
      { value: "0px",label: __("0px") },{ value: "10px",label: __("10px") },{ value: "25px",label: __("25px") },{ value: "50px",label: __("50px") },];

    const paddingBottomOptions = [
      { value: "0px",];

    const {
      setAttributes,attributes: { text_color,font_size,padding_top,padding_bottom },} = this.props;

    let PluginMetaFields = (props) => {
      return (
        <>
          <TextControl
            value={props.text_Metafield}
            label={__("Text Meta","textdomain")}
            onChange={(value) => props.onMetaFieldChange(value)}
          />
        </>
      );
    };
    PluginMetaFields = withSelect((select) => {
      return {
        text_Metafield: select("core/editor").getEditedPostAttribute("Meta")[
          "_myprefix_text_Metafield"
        ],};
    })(PluginMetaFields);

    PluginMetaFields = withdispatch((dispatch) => {
      return {
        onMetaFieldChange: (value) => {
          dispatch("core/editor").editPost({
            Meta: { _myprefix_text_Metafield: value },});
        },};
    })(PluginMetaFields);

    return (
      <InspectorControls key="inspector">
        <PanelBody title={__("Настройки абзаца")}>
          <PanelColorSettings
            title={__("Цвет шрифта")}
            initialOpen={true}
            colorSettings={[
              {
                value: text_color,colors: backgroundColors,onChange: (value) => setAttributes({ text_color: value }),label: __("Цвет шрифта"),},]}
          />
          <SelectControl
            label={__("Размер шрифта")}
            options={fontSizeOptions}
            value={font_size}
            onChange={(value) => this.props.setAttributes({ font_size: value })}
          />
          <SelectControl
            label={__("Отступ сверху")}
            options={paddingTopOptions}
            value={padding_top}
            onChange={(value) =>
              this.props.setAttributes({ padding_top: value })
            }
          />
          <SelectControl
            label={__("Отступ снизу")}
            options={paddingBottomOptions}
            value={padding_bottom}
            onChange={(value) =>
              this.props.setAttributes({ padding_bottom: value })
            }
          />
          <PluginMetaFields />
        </PanelBody>
      </InspectorControls>
    );
  }
}

class HeadlineBlock extends Component {
  render() {
    const {
      attributes: {
        headline,text_color,padding_bottom,alignment,setAttributes,} = this.props;

    const onChangeAlignment = (newAlignment) => {
      this.props.setAttributes({
        alignment: newAlignment === undefined ? "none" : newAlignment,});
    };

    return [
      <Inspector {...{ setAttributes,...this.props }} />,<div>
        {
          <BlockControls>
            <AlignmentToolbar value={alignment} onChange={onChangeAlignment} />
          </BlockControls>
        }
        <RichText
          tagName="p"
          placeholder={__("Текст...")}
          keepPlaceholderOnFocus
          value={headline}
          formattingControls={["bold","italic","strikethrough","link"]}
          className={"font-" + font_size + " post-desc__p-text"}
          style={{
            color: text_color,textAlign: alignment,}}
          onChange={(value) => setAttributes({ headline: value })}
        />
      </div>,];
  }
}

registerBlockType("amm-custom-block/test-block",{
  title: __("Тест блок"),icon: "shield",category: "AMM",attributes: {
    headline: {
      type: "string",alignment: {
      type: "string",default: "none",text_color: {
      type: "string",default: "#525252",font_size: {
      type: "string",default: "14px",padding_top: {
      type: "string",default: "50px",padding_bottom: {
      type: "string",default: "0px",edit: HeadlineBlock,save: function (props) {
    const {
      attributes: {
        headline,} = props;
    return (
      <Fragment>
        {headline && !!headline.length && (
          <RichText.Content
            tagName="p"
            className={"font-" + font_size + " post-desc__p-text"}
            style={{
              color: text_color,paddingTop: padding_top,paddingBottom: padding_bottom,}}
            value={headline}
          />
        )}
      </Fragment>
    );
  },});

到目前为止,仅向该块添加一个文本字段,并试图读取和保存数据。 读取所有内容都可以,但是保存数据不起作用,也没有错误

知道为什么会这样吗?

抱歉,英语不是母语

解决方法

元字段 _myprefix_text_metafield 是受保护的字段,因为它以“ _”(下划线)开头。这就是为什么您可以在withSelect()中读取值,但不通过auth_callback而不能在DisDisatch()中保存该值的原因。

要保存到受保护的字段,请auth_callback is required,例如:

const onSubmit = async (values) => {
    try {
      setError("");
      setLoading(true);
      await login(values.email,values.password);
      authenticateUser();

      await getUserData();

      console.log(userData);
      history.push("/");
    } catch {
      setError("Failed to log in");
    }

    setLoading(false);
  };```

您正在遵循的教程中有一个示例: https://css-tricks.com/managing-wordpress-metadata-in-gutenberg-using-a-sidebar-plugin/#post-291605

或者,如果不需要保护/私有您的元字段:将您的元字段重新注册为 myprefix_text_metafield (名称中没有下划线,并且没有auth_callback),并且您当前的代码可以使用,例如:

<?php
register_post_meta( 'post','_myprefix_text_metafield',array(
    'show_in_rest' => true,'single' => true,'type' => 'string','auth_callback' => function() {
        return current_user_can( 'edit_posts' );
    }) 
);
?>