WordPress Custom Blocks With ACF

The default WordPress editor is fine for simple pages but when looking for more complex layouts, it lacks flexibility and for a web designer, this can be frustrating. I could use a code block but it’s not very professional when it’s for a client who doesn’t know anything about HTML.

The ACF (Advanced Custom Fields) plugin brings the WP editor to a whole new level by allowing you to create your own blocks that meet your requirements. Note that the block feature is only available in the PRO version. Let’s look at a simple example.

Register Your ACF Block

The first thing we need to do is register our custom block. For this tutorial, we’re going to create a “Testimonials” block. Go to your functions.php file and add the following function:

functions.php
add_action('acf/init', 'acf_init_custom_block_types');
function acf_init_custom_block_types() {

    // Check function exists.
    if( function_exists('acf_register_block_type') ) {
        
        // Register block.
        acf_register_block_type(array(
            'name'            => 'testimonials',
            'title'           => __('Testimonials'),
            'description'     => __('Display Testimonials block'),
            'render_callback' => 'acf_block_render_testimonials',
            'category'        => 'formatting',
            'icon'            => 'admin-comments',
            'keywords'        => array( 'testimonial', 'quote' ),
        ));
    }
}

I’m using render_callback to call a function named acf_block_render_product_offer and from there I will be able to have all the logic code separated from the HTML as you’ll see a bit later. But you can also use render_template and directly call a template part file instead.

'render_template' => 'template-parts/blocks/product-offer.php',

Creating Custom Fields

Creating the fields is very simple. In your WordPress admin backend, go to “Custome Fields” and click on “Add New” to create a new field group. At the top, type a descriptive name, so in our case, it could be “Testimonials Block”. Then next we’re going to create our first field with a type of “Repeater”.

ACF repeater field

The “Repeater” field type will allow us to have multiple testimonials in the same block.

Now, in the “Sub Fields” section, we need to create all the fields that we will use in each testimonial.

ACF repeat sub fields

And the last important thing to do on this page is to choose where we want our fields to display in the “Location” section. Select the Testimonials block we registered and then press “Publish” to save everything.

Adding The Block To A Post

Now, create a new page, and you should be able to see the “Testimonials” in the list of blocks. Add it to your editor, create as many testimonials as you want, fill in the fields, and publish.

Getting The Data From The Fields

In part 1, we registered the block and set render_callback to call a function acf_block_render_product_offer. It’s now time to create this function where we set a unique ID, our classes, and loop through every row we’ve created in the backend. In the loop, we also include our template part to display the actual testimonials. In your functions.php file, add the following code:

functions.php
function acf_block_render_testimonials($block){
    // Create block ID
    $id = $block['anchor'] ?? 'testimonial-' . $block['id'];

    // Create class attribute allowing for custom "className" values
    $className = ' testimonials-block';
    if( !empty($block['className']) ) {
        $className .= ' ' . $block['className'];
    }

    // Check rows have been created
    if( have_rows('testimonials') ) {
        // Loop through rows
        echo '<div class="'. $className .'" id="'. $id .'">';
        while( have_rows('testimonials') ) { the_row();
            // Get the values
	    $image = get_sub_field('author_image') ?: 'default-image.jpg';
	    $text = get_sub_field('author_testimonail');
	    $name = get_sub_field('author_name');
	    $role = get_sub_field('author_role');
            
	    // Include template part
	    include get_stylesheet_directory() . '/template-parts/blocks/testimonial.php';
        }
        echo '</div>';
    }
}

Displaying The Rows

Now is the time to build the layout of our testimonials which is pretty simple.

/template-parts/blocks/testimonial.php
<div class="testimonial-item">
    <img src="<?php echo $image; ?>" alt="Author picture" />
    <div class="quote">"<?php echo $text; ?>"</div>
    <div class="author-name"><?php echo $name; ?></div>
    <div class="author-role"><?php echo $role; ?></div>
</div>

Here is the result:

It’s very simple but here is the CSS I’ve used for the design if you are interested.

.testimonials-block {
    display: grid;
    text-align: center;
    grid-template-columns: repeat(3, 1fr);
    gap: 40px;
}

.testimonials-block .testimonial-item {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.testimonials-block img {
    width: 100%;
    border-radius: 100%;
    max-width: 200px;
}

.testimonials-block .quote {
    max-width: 250px;
    font-weight: 600;
    font-style: italic;
    font-size: 1.7rem;
    line-height: 20px;
    margin: 12px 0;
}

.testimonials-block .author-name {
    line-height: 14px;
    font-weight: 600;
    border-top: 1px solid #ccc;
    padding-top: 12px;
}

.testimonials-block .author-role {
    font-size: 1.2rem;
}

Leave a Reply

Your email address will not be published. Required fields are marked *