How to create Gutenberg blocks using Advanced Custom Fields in WordPress
Tags: wordpress, gutenberg, blocks, acf
Published: 2023-07-10 09:13:43

_This tutorial assumes you have a block theme (like Twenty Twenty-Three) and the ACF plugin installed._

Our objective is to create a simple Testimonial block with customisable text, image, text colour and background colour using Advanced Custom Fields.


![End result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iurrhgs39m1snjll1ubi.png)


## 1. Register a Block
First you have to create a JSON file to with the necessary information about the block.

[Documentation for all the metadata options inside block.json](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/)

**blocks/testimonial/block.json**

```json
{
  "name": "acf/testimonial",
  "title": "Testimonial",
  "description": "A custom testimonial block.",
  "style": ["file:./testimonial.css"],
  "category": "formatting",
  "icon": "admin-comments",
  "keywords": ["testimonial", "quote"],
  "acf": {
    "mode": "preview",
    "renderTemplate": "testimonial.php"
  },
  "supports": {
    "align": "false"
  }
}
```
Most of the fields are quite self-explanatory, like [name](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#name), [title](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#name) and [description](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#description). Here we are using [style](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#style) property to assign a stylesheet for this block. You could also use a global stylesheet here. The only [ACF specific fields](https://www.advancedcustomfields.com/resources/acf-blocks-with-block-json/) are _mode_ and _renderTemplate_. We also want to disable [align](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/#align) for this block.


Register the block with WordPress function [register_block_type](https://developer.wordpress.org/reference/functions/register_block_type/) in **functions.php** or equivalent.

**functions.php**

```php
add_action( 'init', 'register_acf_blocks' );
function register_acf_blocks() {
    register_block_type( __DIR__ . '/blocks/testimonial' );
}
```

## 2. Create a Field Group in ACF

In WordPress Admin, create a new field in Custom Fields > Add New with the following fields.


![Creating a field group in ACF](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oz0osm827329mz2r9pgw.png)

Remember to configure the location rule also so that the block shows up correctly in the editor.

## 3. Render the block
We need to create a PHP file with a name that matches the _render_template_ setting inside the **block.json** we created in step 1. 

**blocks/testimonial/testimonial.php**
```php
<?php

/**
 * Testimonial Block Template.
 *
 * @param   array $block The block settings and attributes.
 * @param   string $content The block inner HTML (empty).
 * @param   bool $is_preview True during backend preview render.
 * @param   int $post_id The post ID the block is rendering content against.
 *          This is either the post ID currently being displayed inside a query loop,
 *          or the post ID of the post hosting this block.
 * @param   array $context The context provided to the block by the post or it's parent block.
 */


// Load values and assign defaults.
$text             = get_field('testimonial') ?: 'Your testimonial here...';
$author           = get_field('author') ?: 'Author name';
$image            = get_field('avatar') ?: null;
$background_color = get_field('background_color') ?: '';
$text_color       = get_field('color') ?: '';

// Build a valid style attribute for background and text colors.
$styles = array('background-color: ' . $background_color, 'color: ' . $text_color);
$style  = implode('; ', $styles);

?>
<div class="testimonial-block" style="<?php echo esc_attr($style); ?>">
    <blockquote class="testimonial-blockquote">
        <p class="testimonial-text"><?php echo esc_html($text); ?></span>
        <p class="testimonial-author"><?php echo esc_html($author); ?></span>
    </blockquote>
    <div class="testimonial-image">
        <?php if ($image) : ?>
            <?php echo wp_get_attachment_image($image['id'], 'full'); ?>
        <?php endif; ?>
    </div>
</div>
```
In the template we first load the values from all the fields using `get_field()`. Then we get the styles from the color pickers and output them as inline styles. Finally we create the block html and echo the values.

## 4. Create the stylesheet for the block
Finally, let's create a basic stylesheet for our shiny new block using CSS Grid.
**blocks/testimonial/testimonial.css**
```css
.testimonial-block{
    display: grid;
    grid-template-columns: 1fr 200px;
    padding: 1rem;
}

.testimonial-image img{
    max-width: 100%;
    aspect-ratio: 1/1;
    width: 100%;
    height: auto;
    border-radius: 9999px;
    object-fit: cover;
}
```
Done!

### Further reading:
- https://www.advancedcustomfields.com/resources/blocks/
- https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/
- https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/