Gutenberg: Help: Server Render <InnerBlocks.Content /> in a dynamic block

Created on 26 Jun 2019  路  2Comments  路  Source: WordPress/gutenberg

I am trying to figure out how to access from my dynamic block as I would in the save function.

Here is an example

function register_dynamic_block() {

  if (!function_exists('register_block_type')) {
    return;
  }

  register_block_type('example/hero-block', array(
    'attributes' => array(
      'message' => array(
        'type' => 'html',
      ),
      'label' => array(
        'type' => 'html',
      ),
      'type' => array(
        'type' => 'string',
        'default' => 'default',
      ),
      'subtitleSwitch' => array(
        'type' => 'boolean',
        'default' => false,
      ),
      'subtitle' => array(
        'type' => 'html',
      ),
      'image' => array(
        'type' => 'string',
        'default' => null,
      ),
      'blockAlignment' => array(
        'type' => 'string',
        'default' => 'full',
      ),
    ),

    'render_callback' => __NAMESPACE__ . '\render_dynamic_block'
  ));
}

function render_dynamic_block($attributes) {
  $message = $attributes['message'];
  $label = $attributes['label'];
  $type = $attributes['type'];
  $subtitleSwitch = $attributes['subtitleSwitch'];
  $subtitle = $attributes['subtitle'];
  $image = $attributes['image'];
  $blockAlignment = $attributes['blockAlignment'];

  ob_start(); // Turn on output buffering

?>
  <div class="wp-block-hero-block <?php echo "align$blockAlignment" ?> <?php echo "type-$type" ?>">
    <div class="layer-container">
      <div class="flex-container">
        <div class="hero-label">
          <h2 class="hdg_4">
            <?php echo $label; ?>
          </h2>
        </div>
        <div class="hero-body">
          <h1>
            <?php echo $message; ?>
          </h1>
        </div>
        <div class="subtitle-body">
          NEED INNER BLOCK CONTENT
        </div>
      </div>
    </div>
    <?php if (isset($image)) {
      echo "<div class='bg-image'><img src='$image' alt='$image' /></div>";
    } ?>
  </div>
<?php

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

  return $output; // Print output
}

I have tried what seems to be suggested here https://github.com/WordPress/gutenberg/issues/6751
But it doesn't seem to work for dynamic blocks

function register_dynamic_block() {

  if (!function_exists('register_block_type')) {
    return;
  }

  register_block_type('example/hero-block', array(
    'attributes' => array(
      'message' => array(
        'type' => 'html',
      ),
      'label' => array(
        'type' => 'html',
      ),
      'type' => array(
        'type' => 'string',
        'default' => 'default',
      ),
      'subtitleSwitch' => array(
        'type' => 'boolean',
        'default' => false,
      ),
      'subtitle' => array(
        'type' => 'html',
      ),
      'image' => array(
        'type' => 'string',
        'default' => null,
      ),
      'blockAlignment' => array(
        'type' => 'string',
        'default' => 'full',
      ),
    ),

    'render_callback' => __NAMESPACE__ . '\render_dynamic_block'
  ));
}

function render_dynamic_block($attributes, $content) {
  return $content
}
[Feature] Nested / Inner Blocks [Type] Help Request

Most helpful comment

For anyone looking for a possible solution to this problem: It is possible to mix the two. This works for my situation as the reason I am using dynamic blocks is so I can make bug fixes without needing to update every single block.

my solution was to not server render the inner blocks.

save: props => {
  return <InnerBlocks.Content />
}

Then on the php side I pass in $content and echo that

...
function render_dynamic_block($attributes, $content) {
  $message = $attributes['message'];
  $label = $attributes['label'];
  $type = $attributes['type'];
  $subtitleSwitch = $attributes['subtitleSwitch'];
  $subtitle = $attributes['subtitle'];
  $image = $attributes['image'];
  $blockAlignment = $attributes['blockAlignment'];

  ob_start(); // Turn on output buffering

?>
  <div class="wp-block-hero-block <?php echo "align$blockAlignment" ?> <?php echo "type-$type" ?>">
    <div class="layer-container">
      <div class="flex-container">
        <div class="hero-label">
          <h2 class="hdg_4">
            <?php echo $label; ?>
          </h2>
        </div>
        <div class="hero-body">
          <h1>
            <?php echo $message; ?>
          </h1>
        </div>
        <div class="subtitle-body">
          <?php echo $content ?>
        </div>
      </div>
    </div>
    <?php if (isset($image)) {
      echo "<div class='bg-image'><img src='$image' alt='$image' /></div>";
    } ?>
  </div>
<?php
  /* END HTML OUTPUT */

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

  return $output; // Print output
}
...

All 2 comments

For anyone looking for a possible solution to this problem: It is possible to mix the two. This works for my situation as the reason I am using dynamic blocks is so I can make bug fixes without needing to update every single block.

my solution was to not server render the inner blocks.

save: props => {
  return <InnerBlocks.Content />
}

Then on the php side I pass in $content and echo that

...
function render_dynamic_block($attributes, $content) {
  $message = $attributes['message'];
  $label = $attributes['label'];
  $type = $attributes['type'];
  $subtitleSwitch = $attributes['subtitleSwitch'];
  $subtitle = $attributes['subtitle'];
  $image = $attributes['image'];
  $blockAlignment = $attributes['blockAlignment'];

  ob_start(); // Turn on output buffering

?>
  <div class="wp-block-hero-block <?php echo "align$blockAlignment" ?> <?php echo "type-$type" ?>">
    <div class="layer-container">
      <div class="flex-container">
        <div class="hero-label">
          <h2 class="hdg_4">
            <?php echo $label; ?>
          </h2>
        </div>
        <div class="hero-body">
          <h1>
            <?php echo $message; ?>
          </h1>
        </div>
        <div class="subtitle-body">
          <?php echo $content ?>
        </div>
      </div>
    </div>
    <?php if (isset($image)) {
      echo "<div class='bg-image'><img src='$image' alt='$image' /></div>";
    } ?>
  </div>
<?php
  /* END HTML OUTPUT */

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

  return $output; // Print output
}
...

I have done the same thing to solve my projects
save: () => { return ( <div> <InnerBlocks.Content /> </div> ); },

and in PHP code just use the $content to access & display the inner blocks. But I am little confused about this procedure.

There should be some exact declaration or documentation "How to use InnerBlock in perfect way".

[FYI, I don't know if the documentation about this already exists now. peace ... 馃帀 ]

Was this page helpful?
0 / 5 - 0 ratings