Site icon Hip-Hop Website Design and Development

How do I dynamically render an InnerBlock inside a dynamic block?

I am building a custom website with custom blocks and have recently decided to translate all my blocks into dynamic blocks. The blocks that do not use InnerBlocks are fine, but I cannot figure out how to render a dynamic InnerBlock inside another dynamic block.

I used the advice from another post to mix the save() method and return InnerBlocks.Content, after which you render the InnerBlocks content with $content inside the render_callback function. This is what it looks like:

// counter/save.js
import { __ } from "@wordpress/i18n";
import { InnerBlocks } from "@wordpress/block-editor";

const Save = (props) => {
  return <><InnerBlocks.Content /></>;
};
export default Save;
// counter.php
function counter_render_callback($attr, $content)
{
  ob_start(); // Turn on output buffering

?>

  <?php if (!empty($content)) : ?>
  <section class="bg-blue-900 thin text-white">
    <div class="container flex flex-wrap justify-evenly md:justify-around text-center -mb-10 md:mb-0">
      <?php echo do_blocks($content); ?>
    </div>
  </section>
  <?php endif; ?>

<?php
  /* END HTML OUTPUT */

  $output = ob_get_contents(); // collect output
  ob_end_clean(); // Turn off ouput buffer

  return $output; // Print output
};

Now I set up my InnerBlock to also act as a dynamic block, but it only renders that which I set up in it’s save.js file. This is what the InnerBlock looks like:

// counter-list/save.js
import { __ } from "@wordpress/i18n";
import { useBlockProps } from "@wordpress/block-editor";

const Save = (props) => {
  const { attributes } = props;

  const mandatoryFields = () => {
    return attributes.amount && attributes.label;
  };

  const blockProps = useBlockProps.save();
  return (
    <div {...blockProps}>
      {mandatoryFields() && (
        <div class="w-1/2 sm:w-1/3 md:w-auto mb-10 md:mb-0">
          <div class="font-display text-h1 font-medium leading-none">
            {attributes.amount}
          </div>
          <div class="w-10 h-px bg-white my-4 inline-block opacity-60"></div>
          <div>{attributes.label}</div>
        </div>
      )}
    </div>
  );
};
export default Save;
// counter-list.php
function counter_list_render_callback($attr, $content)
{
  // Easier access to all attributes
  $amount = !empty($attr['amount']) ? $attr['amount'] : "";
  $label = !empty($attr['label']) ? $attr['label'] : "";

  // Do not output anything if any of the mandatory fields are empty
  if (empty($amount) || empty($label)) {
    return;
  }

  ob_start(); // Turn on output buffering

?>

<div class="w-1/2 sm:w-1/3 md:w-auto mb-10 md:mb-0">
  <div class="font-display text-h1 font-medium leading-none"><?php echo $amount; ?></div>
  <div class="w-10 h-px bg-white my-4 inline-block opacity-60"><?php echo $label; ?></div>
</div>

<?php
  /* END HTML OUTPUT */

  $output = ob_get_contents(); // collect output
  ob_end_clean(); // Turn off ouput buffer

  return $output; // Print output
};

How do I make my counter.php file use the render_callback function from counter-list.php?