Create a Gutenberg Block with Advanced Custom Fields

This tutorial requires the Pro version of Advanced Custom Fields.

If you know me I tend to bang on about my love for Advanced Custom Fields quite a bit so I’m going to be creating a few tutorials on using this awesome plugin!

In the first of this series, I’m going to go through my process of creating a Gutenberg block with ACF. The block we will be creating will list the most recent posts and will offer a few options such as, adding a heading, limiting how many posts we want to show and an option to show the featured image or not.

1. Let’s register ACF blocks

First up, in our functions.php file, we are going to hook into acf/init with our custom feh_acf_custom_blocks function.

if(function_exists('acf_register_block')) 
{ 
   add_action('acf/init', 'feh_acf_custom_blocks');
}

Next, we will create this feh_acf_custom_blocks function. This is the part where we create our Gutenberg block.

function feh_acf_custom_blocks() 
{ 
   if (function_exists('acf_register_block'))
   {
      acf_register_block 
      (
         array 
         (
            'name'              => 'recent-posts',
            'title'             => __('Recent Posts'),
            'description'       => __('Recent posts block'),
            'render_callback'   => 'feh_recent_posts_callback',
            'category'          => 'feh',
            'keywords'          => array( 'feh', 'recent', 'posts' ),
         )
      );
   }
}

Breakdown of our acf_register_block array

  • name: The name assigned to our block
  • title: The title that will display to users, adding our block
  • description: Short description about what our block does
  • render_callback: Callback function that will house our block content
  • category: A category to hold our blocks
  • keywords: Keywords associated with block, to be used for searching through blocks

2. Creating our new block category

As we are going to use a block category to hold our block, (‘category’ => ‘feh’), we now have to create this function and hook into the block_categories filter. This part is straightforward and only requires a few lines of code with two options; slug and title.

Make sure the slug matches the category name in the category value, in the acf_register_block array.

function feh_category( $categories, $post ) 
{
   return array_merge
   (
      $categories, array
      (
         array
         (
            'slug' => 'feh',
            'title' => __('FEH Blocks', 'feh'),
         ),
      )
   );
}
add_filter( 'block_categories', 'feh_category', 10, 2);

3. Creating our ACF block fields

With all of the above code in place, we now want to create our ACF field group for our recent posts block.

Go to your custom fields menu and create a new field group as your normally would but instead of showing the group in a post or page, scroll down to the second last item of the dropdown menu in the location area and select block. Then link the Recent Posts block.

Add some fields to our recent posts block

With our block created and linked up successfully, all that’s left to do is add some field options to our block and add some basic styling.

I have created three fields that I hope are self explanatory.

4. Creating our block code

Earlier when we created the acf_register_block array, we used render_callback to link to our recent posts block. We now need to create this block to output our block content.

'render_callback'   => 'feh_recent_posts_callback',

In our functions.php file, create a function with the name of the value we used for our render_callback option.

I’m not going to go into too much detail here, but basically, I have created #recent-posts section, included our ACF fields, and used a custom WordPress loop to output our posts.

function feh_recent_posts_callback( $block ) 
{
   $align_class = $block['align'] ? 'align' . $block['align'] : ''; 
   $class_name = isset($block['className']) ? $class_name : ""; ?>

   <section id="recent-posts" class="<?php echo $class_name . $align_class; ?>">

      <?php
      $heading = get_field('heading');
      $how_many_posts_to_show = get_field('how_many_posts_to_show');
      $include_image = get_field('include_image'); ?>

      <h3><?php echo $heading; ?></h3>
	
      <div class="grid grid-<?php echo $how_many_posts_to_show; ?>">
      <?php 

      $args = array
      (
         'post_type' => 'post',
         'posts_per_page' => $how_many_posts_to_show
      );

      $news_posts = new WP_Query($args);
      while($news_posts->have_posts()) : $news_posts->the_post(); ?>

         <div <?php post_class(); ?> id="post-<?php the_ID(); ?>">

            <?php if($include_image) { ?>
               <a href="<?php the_permalink(); ?>">
                  <?php the_post_thumbnail(); ?>
               </a>
            <?php } ?>

            <p class="date"><?php echo get_the_date(); ?></p>
            <h4><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4>
            <p class="excerpt"><?php echo get_the_excerpt(); ?></p>
            <a href="<?php the_permalink(); ?>">Read more</a>
         </div>

      <?php endwhile; ?>
      <?php wp_reset_postdata(); // reset the query ?>
      </div>

   </section>

<?php } ?>

5. Adding our block to a page

Finally, we can add our newly created block to a page!

Once you add the block to the page, switch to edit mode and you will see all of the custom fields we created.

… then by adding a basic grid with CSS (adding classes for the 4 different coloumn sizes), you should something like below.

You can reply to this post by tweeting to me