snow covered mountain during daytime

Case: do_blocks Function with ACF Repeater Fields

  • ElPuas

  • 10/17/2023

In a previous post, we explored leveraging PHP Templates in the Site Editor. I briefly touched on the do_blocks() function, a WordPress feature for rendering dynamic blocks within posts. Let’s dive into a real-world scenario where do_blocks() handle Advanced Custom Fields (ACF) Repeater Fields for a dynamic audio block rendering.

I was working with a page dynamically generated through Gravity Forms' Advanced Post Creation add-on. Users could upload audio files via a form, which would then populate an ACF repeater field on the generated post. However, I wanted to step beyond merely listing links to these audio files. I aimed for a more engaging user interface, where the audio content is readily playable. This is where the do_blocks() function came into the picture, enabling the rendering of audio blocks instead of plain URLs.

Here’s a function I did for this purpose:

function render_audio_blocks($repeater_field) {
    $blocks_markup = '';
    foreach ($repeater_field as $item) {
        $file_name = basename($item['audio'], ".mp3");
        $blocks_markup .= "<!-- wp:audio -->
          <figure class=\"wp-block-audio\">
            <audio controls src=\"{$item['audio']}\"></audio>
            <figcaption class=\"wp-element-caption\">{$file_name}</figcaption>
        </figure><!-- /wp:audio -->";
    }
    return $blocks_markup;
}

Let's break down this function, the render_audio_blocks function takes one argument, $repeater_field, which is expected to be an array of items, each containing an audio file URL under the key 'audio'.

- It initializes an empty string $blocks_markup.
- Iterates through $repeater_field with a for each loop, processing each $item.
- Extracts the file name from the URL, excluding the ".mp3" extension, using basename().
- Appends a WordPress audio block markup for each item to $blocks_markup, with the audio source and file name as the caption.
- After processing all items, it returns the concatenated $blocks_markup, ready to be rendered in the WordPress post.

And this is how I implemented my template:

<head>
  <meta charset="<?php bloginfo( 'charset' ); ?>">
  <?php
  $repeater_field = get_field( 'audios', get_the_ID() );
  $audio_blocks = render_audio_blocks($repeater_field);
  ?>
  <?php wp_head(); ?>
</head>
<body>
...
<?php echo !empty($audio_blocks) ? $audio_blocks : ''; ?>
...

Why in the head? WordPress 6.0 brought a shift in how blocks support CSS loads - in the head for block themes, and in the body for classic PHP-based themes. This change is traced back to GitHub pull request #39164 and #38750, means using do_blocks() post wp_head() skips block CSS loading, a crucial detail for our setup.

So, the workaround was to place the block markup in do_blocks() before wp_head() and echo it within the template body. This tweak ensured the block CSS loads correctly, making my audio blocks render as intended.

I hope this dive into utilizing do_blocks() with ACF Repeater Fields has provided valuable insights for your own WordPress projects. If you found this post helpful, feel free to share it with your network and follow for more insights on WordPress development. Until next time, happy coding!

© 2024 Built with Gatsby by El.Puas