Skip to main content

Delicious Reverie

blog of developer & bookworm benjamin read

Advanced Custom Fields and Bootstrap Tabs

I'm not a huge fan of Advanced Custom Fields, but there was a requirement to use it in a recent project that had Bootstrap as a basis for the UI. The challenge for me was to get Bootstrap nav-tabs to play nice with an ACF repeater field.

I started with the basic HTML markup for Bootstrap's Nav Tabs:

<ul class="nav nav-tabs">
  <li role="presentation" class="active"><a href="tabone">TabOne</a></li>
  <li role="presentation"><a href="tabtwo">TabTwo</a></li>
  <li role="presentation"><a href="tabthree">TabThree</a></li>
</ul>
<div class="tab-content">
  <div class="tab-pane active" id="tabone">
     Some content in tab one
</div>
  <div class="tab-pane active" id="tabtwo">
     Some content in tab two
</div>
  <div class="tab-pane active" id="tabthree">
     Some content in tab three
</div>
</div>

In the Field Groups settings, I created a Repeater (this is a paid-for add on to the standard Advanced Custom Fields) called "tab Panes", with 2 sub-fields, "Tab Title" and "Tab Contents".

<?php
<!-- Check for parent repeater row -->
<?php if( have_rows('tab_panes') ): ?>
  <ul class="nav nav-tabs" role="tablist">
  <?php // Step 1: Loop through rows, first displaying tab titles in a list
   while( have_rows('tab_panes') ): the_row();
?>
    <li role="presentation" class="active">
      <a
        href="#tabone"
        role="tab"
        data-toggle="tab"
        >
      <?php the_sub_field('tab_title'); ?>
      </a>
    </li>
    <?php endwhile; // end of (have_rows('tab_panes') ):?>
  </ul>
<?php endif; // end of (have_rows('tab_panes') ): ?>

The PHP above displays the tabs. The code below, very similarly, displays the tab panes:

<?php if( have_rows('tab_panes') ): ?>
  <div class="tab-content">
  <?php// number rows ?>
  <?php // Step 2: Loop through rows, now displaying tab contents
   while( have_rows('tab_panes') ): the_row();
  // Display each item as a list ?>
      <div class="tab-pane active" id="tabone">
          <?php the_sub_field('tab_contents'); ?>
      </div>
      <?php endwhile; // (have_rows('tab_panes') ):?>
  </div>
<?php endif; // (have_rows('tab_panes') ): ?>

By looping through the same repeater, we can get all the tabs out of the database, no problem. But we still have two problems: 1) linking the tab to the pane 2) Assigning the class of "active" so the Javascript is able to add and remove the CSS to reveal / hide the appropriate pane.

1) Linking to the Pane

There are a number of ways to do this. I could ask the user to input a number to uniquely identify the tab pane. But that would add extra work to the users flow, and they might easily find themselves out of their depth. I want to make this as easy as possible for the user.

On the other hand, Wordpress has a very useful function called Sanitize HTML, which we input the value of the title, take out spaces and capitals, and use this as the link:

<a href="#<?php echo sanitize_html_class( the_sub_field( 'tab_title' ) ); ?>"

2) Assigning the 'Active' Class

So now we need to get a class of 'active' only on the first tab. The Bootstrap Javascript will do the rest for us. How do we do that?

I added this code just inside the while loop, inside the ul tag:

<?php $row = 1; // number rows ?>

This php is a counter. So we can identify the first instance and assign an if statement to it.

<a class="<?php if($row == 1) {echo 'active';}?>">

The final thing to do, is to keep the counter running, but adding this jsut before the endwhile.

<?php $row++; endwhile; // (have_rows('tab_panes') ):?>

Once you've added these to the tab panes in a similar way, you'll be up and running with Boostrap Tabs.

Below is a Github Gist, with the complete code for reference. Link to this (if you can't see the iFrame).


You're currently on the javascript disabled version of the site. To enable the site search and some pretty animations, view the javascript enabled react app.

About This Site

Delicious Reverie is the blog of developer & bookworm benjamin read. Set in Skybird and your system font. Built with Gatsby, hosted by Netlify. © Some rights are reserved. This site doesn't use any cookies or other session storage and has no tracking scripts.

Where you can find me: