admin管理员组

文章数量:1277338

I have two gutenberg blocks to make up an accordion. The parent accordion uses InnerBlocks with allowedBlocks set to just the panel block. So the two blocks are:

ea/accordion
ea/accordion-panel

Each panel has two elements, a heading for the panel (using RichText) and InnerBlocks with the content. When I save the accordion, only the InnerBlocks content is being saved. How can I save the heading as well?


More detail:

The ea/accordion-panel has the following index.js

registerBlockType("ea/accordion-panel", {
  parent: ["ea/accordion"],

  attributes: {
    heading: {
      type: "string",
      source: "html",
      selector: "h2",
    },
  },

  edit: Edit,

  save,
});

And the following edit function:

export default function Edit({ attributes, setAttributes }) {
  return (
    <div {...useBlockProps({ className: "ea-accordion-panel" })}>
      <div className="ea-accordion-panel--title">
        <RichText
          tagName="h2"
          value={attributes.heading}
          onChange={(heading) => setAttributes({ heading })}
          placeholder={__("Heading...")}
        />
      </div>
      <InnerBlocks />
    </div>
  );
}

But it is only the InnerBlocks content that is shown in the editor after saving. (not the heading, even though this is set and stored in attributes)

The ea/accordion itself doesn't store any attributes, so maybe this is where the error is?

accordion/index.js

import { registerBlockType } from "@wordpress/blocks";

import "./style.scss";
import Edit from "./edit";
import save from "./save";

registerBlockType("ea/accordion", {
  edit: Edit,
  save,
});

accordion edit function:

export default function Edit() {
  const blockProps = useBlockProps({ className: "ea-accordion" });

  return (
    <div {...blockProps}>
      <InnerBlocks allowedBlocks={["ea-accordion-panel"]} />
    </div>
  );
}

Before saving, here we have

accordion 
  InnerBlocks
    accordion-panel
      heading => A new heading
      InnerBlocks
        Paragraph => Some content
    accordion-panel
      heading => Another heading
      InnerBlocks
        Paragraph => Some more content

Then after save...

accordion 
  InnerBlocks
    accordion-panel
      heading => empty
      InnerBlocks
        Paragraph => Some content
    accordion-panel
      heading => empty
      InnerBlocks
        Paragraph => Some more content


Update

I found the issue, the save function looked like this:

<div {...blockProps}>
  <!-- No heading tag -->
  <div className="ea-accordion-panel--content">
    <InnerBlocks.Content />
  </div>
</div>

I have two gutenberg blocks to make up an accordion. The parent accordion uses InnerBlocks with allowedBlocks set to just the panel block. So the two blocks are:

ea/accordion
ea/accordion-panel

Each panel has two elements, a heading for the panel (using RichText) and InnerBlocks with the content. When I save the accordion, only the InnerBlocks content is being saved. How can I save the heading as well?


More detail:

The ea/accordion-panel has the following index.js

registerBlockType("ea/accordion-panel", {
  parent: ["ea/accordion"],

  attributes: {
    heading: {
      type: "string",
      source: "html",
      selector: "h2",
    },
  },

  edit: Edit,

  save,
});

And the following edit function:

export default function Edit({ attributes, setAttributes }) {
  return (
    <div {...useBlockProps({ className: "ea-accordion-panel" })}>
      <div className="ea-accordion-panel--title">
        <RichText
          tagName="h2"
          value={attributes.heading}
          onChange={(heading) => setAttributes({ heading })}
          placeholder={__("Heading...")}
        />
      </div>
      <InnerBlocks />
    </div>
  );
}

But it is only the InnerBlocks content that is shown in the editor after saving. (not the heading, even though this is set and stored in attributes)

The ea/accordion itself doesn't store any attributes, so maybe this is where the error is?

accordion/index.js

import { registerBlockType } from "@wordpress/blocks";

import "./style.scss";
import Edit from "./edit";
import save from "./save";

registerBlockType("ea/accordion", {
  edit: Edit,
  save,
});

accordion edit function:

export default function Edit() {
  const blockProps = useBlockProps({ className: "ea-accordion" });

  return (
    <div {...blockProps}>
      <InnerBlocks allowedBlocks={["ea-accordion-panel"]} />
    </div>
  );
}

Before saving, here we have

accordion 
  InnerBlocks
    accordion-panel
      heading => A new heading
      InnerBlocks
        Paragraph => Some content
    accordion-panel
      heading => Another heading
      InnerBlocks
        Paragraph => Some more content

Then after save...

accordion 
  InnerBlocks
    accordion-panel
      heading => empty
      InnerBlocks
        Paragraph => Some content
    accordion-panel
      heading => empty
      InnerBlocks
        Paragraph => Some more content


Update

I found the issue, the save function looked like this:

<div {...blockProps}>
  <!-- No heading tag -->
  <div className="ea-accordion-panel--content">
    <InnerBlocks.Content />
  </div>
</div>
Share Improve this question edited Sep 30, 2021 at 14:08 Djave asked Sep 30, 2021 at 9:23 DjaveDjave 2584 silver badges25 bronze badges 3
  • can you include your save component? And clearly label it? There are a lot of code blocks and it's unclear which code belongs to what. You also mention there are two blocks yet there are no save components in your question, i expected to see 2. The save component is the most important and relevant code to your question, it is absolutely necessary – Tom J Nowell Commented Sep 30, 2021 at 10:05
  • 1 @TomJNowell oh god, a) sorry I definitely should have included that b) surprise surprise I didn't include the RichText.Content so wasn't saving it :facepalm. Thank you, your comment helped me fix it. – Djave Commented Sep 30, 2021 at 13:10
  • 1 can you update your question and write an answer so others with this problem know what to do? – Tom J Nowell Commented Sep 30, 2021 at 13:22
Add a comment  | 

1 Answer 1

Reset to default 0

I had checked everywhere except the save function (see updated question). I updated it as follows:

<div {...blockProps}>
  <div className="ea-accordion-panel--heading">
    <RichText.Content tagName="h2" value={attributes.heading} />
  </div>
  <div className="ea-accordion-panel--content">
    <InnerBlocks.Content />
  </div>
</div>

本文标签: Store data from nested block of gutenberg