Learn How To code a Bootstrap Carousel Block for your WordPress theme. ACF Pro required.
Today I will show you how to code a Boostrap Carousel Block for Gutenberg that allows you to use the Bootstrap Carousel in WordPress. I will use Advanced Custom Fields Pro, as I always use this plugin my projects.
If you’re familiar with WordPress and Bootstrap, then you probably know that Bootstrap is a popular framework for building responsive websites. It has been my go to framework since I started building WordPress websites in 2014.
One of the most useful components of Bootstrap is the Carousel, which allows you to display a series of images in a slideshow format.
I hope it goes without saying, that this tutorial requires you to include Bootstrap in your project. This tutorial is for Bootstrap v.5.2.x. If you are not already using Bootstrap, then you can get started with Bootstrap here.
Now, if you’re not interested in the tutorial, but just the code. Either skip to the end, or go to my Github Repo to find the code and setup guide there.
Let’s start!
The first step is to install and activate the Advanced Custom Fields Pro plugin. This plugin allows you to create custom fields for your Gutenberg Block, which I’ll use to create the Carousel content.
As a WordPress Theme Developer, I can recommend you to invest in ACF Pro, as it makes much of your work easier, when working directly with clients.
First, we need to register a new block component in our functions.php
file in our WordPress theme. Unless this is core functionality in your custom WordPress theme, then I recommend you to use a Child theme.
Add the following lines of code to your functions.php
file.
add_action('acf/init', 'my_acf_blocks_init');
function my_acf_blocks_init() {
// Check function exists.
if( function_exists('acf_register_block_type') ) {
// Register a carousel block.
acf_register_block_type(array(
'name' => 'bootstrap-carousel',
'title' => __('Carousel'),
'description' => __('A slideshow component for cycling through elements—images or slides of text—like a carousel.'),
'render_template' => 'template-parts/blocks/bootstrap-carousel/bootstrap-carousel.php',
'category' => 'formatting',
'keywords' => array( 'carousel', 'bootstrap' ),
'enqueue_assets' => function()
{
wp_enqueue_style( 'css-bootstrap-carousel', get_stylesheet_directory_uri() . '/template-parts/blocks/bootstrap-carousel/bootstrap-carousel.css', array(), '1.0.0' );
},
));
}
}
After successfully registering your block, then it is time to set up your render_template
and CSS file. Go to your theme and create the following directory path /template-parts/blocks/bootstrap-carousel/
. Inside the /bootstrap-carousel/
folder you need to add to files.
bootstrap-carousel.php
bootstrap-carousel.css
The first one is your render_template
and the second one is where your CSS goes.
Inside the render_template
you add the following code.
<?php
/**
* Carousel Block Using Bootstrap v5.2.x
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
// Create id attribute allowing for custom "anchor" value.
$id = 'bootstrap-carousel-id-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'bootstrap-carousel';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
?>
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
</div>
Now your base render_template
is ready.
The stylesheet called bootstrap-carousel.css is the same directory. This is to make sure the styles are only applied when the block is used on a page. This way we avoid unnecessary styles being loaded to keep the project lean and clean.
For now, my CSS file looks like this:
/* =Bootstrap Carousel
-------------------------------------------------------------- */
For my carousel, I want a Carousel with Captions, and controls, but no indicators. For that I go to the Bootstrap documentation and copy the With Captions example. Then I insert this into my render_template
. Last, but not least, I clean it up, so that it looks like this.
<div id="<?php echo esc_attr($id); ?>" class="<?php echo esc_attr($className); ?>">
<div id="bootstrapCarouselACF" class="carousel slide" data-bs-ride="false">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>First slide label</h5>
<p>Some representative placeholder content for the first slide.</p>
</div>
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>Second slide label</h5>
<p>Some representative placeholder content for the second slide.</p>
</div>
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
<div class="carousel-caption d-none d-md-block">
<h5>Third slide label</h5>
<p>Some representative placeholder content for the third slide.</p>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#bootstrapCarouselACF" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#bootstrapCarouselACF" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
</div>
After my initial setup, it’s time for me to head back into WordPress. Here’s where the Pro version of ACF is needed as I’ll be using the Repeater Field option.
Inside the Repeater field I have the option to create so called Sub Fields. These are fields that only exist inside the Repeater Field. Here I need to create an image, a headline, and a paragraph option.
Here is how I created my image field.
Field Label: Image
Field Name: carousel_image
Then we want the option of a caption. I’ll start off with a caption headline.
Field Label: Heading
Field Name: carousel_caption_heading
Then finally, a paragraph section for more descriptive text.
Field Label: Paragraph
Field Name: carousel_caption_paragraph
To make sure my Custom Fields are only shown when my block is selected, I go to the Settings tab. For Location Rules I select to Show this field group if: Block is equal to Carousel.
I save my changes and go to a page to add my newly created block. This is how it looks like, after I added my Carousel Block to a page.
Time to return to my render_template. Find the <div class="carousel-inner">
as this is where our repeater fields belong. Remove everything inside the <div>
and replace it with this code:
<?php if( have_rows( 'bootstrap_carousel_repeater' ) ): ?>
<?php while( have_rows( 'bootstrap_carousel_repeater' ) ): the_row();
// Load the sub_fields created in ACF
$image = get_sub_field('carousel_image');
$heading = get_sub_field('carousel_caption_heading');
$paragraph = get_sub_field('carousel_caption_paragraph');
if (get_row_index() == 1) {
$active = ' active';
} else {
$active = '';
}
?>
<div class="carousel-item carousel-item-<?php echo get_row_index(); ?> <?php echo $active; ?>">
<?php
// Check if there's an image selected
if( !empty( $image ) ): ?>
<figure class="adaptive">
<picture class="adaptive-photo">
<img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>" />
</picture>
</figure>
<?php endif; ?>
<div class="carousel-caption">
<?php if( $heading || $paragraph) : ?>
<div class="carousel-caption__inner">
<?php
// Check if the headline field is empty
if( !empty( $heading ) ): ?>
<h5>
<?php echo $heading; ?>
</h5>
<?php endif; ?>
<?php
// Check if the paragraph field is empty
if( !empty( $paragraph ) ): ?>
<p>
<?php echo $paragraph; ?>
</p>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
The code adds your image, headline and paragraph and sets the first of your images to be active, as this is important for Bootstrap. Without the active class, nothing would be shown on the page.
This is how my Bootstrap Carousel Block is currently looking like.
Personally, I’m not too happy about how the default Bootstrap Caption looks like. Therefor I added a bit of different structure in the carousel-item
. That allowed me to style the look using my CSS file. You can add your own style or be inspired by mine.
/* =Bootstrap Carousel
-------------------------------------------------------------- */
.carousel-caption {
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.carousel-caption__inner {
max-width: 89.375rem;
background: rgba(0,0,0,0.25);
padding: 1rem 2rem;
margin: 0 .75rem;
text-align: left;
}
.carousel-caption__inner h5 {
color: #fff;
}
.carousel-caption__inner p {
margin-bottom: 0;
}
.carousel-item .adaptive .adaptive-photo {
height: 560px;
}
In case you are missing my .adaptive-photo
style, that makes sure the image are always scaled correct to avoid stretching:
/* =Adaptive photo
-------------------------------------------------------------- */
.adaptive {
display: flex;
flex-wrap: wrap;
}
.adaptive .adaptive-photo {
flex-grow: 1;
height: /* set a default height */;
}
.adaptive .adaptive-photo img {
max-height: 100%;
min-width: 100%;
height: 100%;
width: 100%;
object-fit: cover;
object-position: center;
vertical-align: bottom;
}
Was this all a bit much, and you would just like my source code? Fair enough. I’ve added it to Github for you to easily Copy and Paste it into your project. You’re also welcome to check out my Github Repo for the Bootstrap Carousel Block.