Bootstrap-карусель через кастомные поля ACF в Вордпрессе

Углубляемся в изучение ACF (Advanced Custom Fields). Начало в уроке Как сделать одностраничник на Вордпресс — работа с ACF.

Откроем опять Velocee. Проскроллим вниз и увидим бутстрап-карусель (где кроссовки).

Здесь у меня простейший вариант — я знаю, что будет всего 2 слайда, при этом меняется только текст внутри, фоновая картинка остается прежней. То есть по сути карусель статична. И мы можем вывести два текста как два Произвольных поля через плагин ACF.

Код в шаблоне:

<div class="carousel_bg">
<div class="container">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
</ol>

<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active screen08">
<div class="container">
<h1><?php echo get_field('text_for_slider_first_frame'); ?></h1>
</div>
</div><!-- /item -->
<div class="item screen08">
<div class="container">
<h1><?php echo get_field('text_for_slider_second_frame'); ?></h1>
</div>
</div><!-- /item -->
</div>
</div>
</div>
</div><!-- /row -->

Класс carousel_bg выводит фон (фиксированный, адаптивный и т.п.). Дальше идет сама карусель. Тут все предельно понятно. Создаем два поля в Кастомных полях (Custom Fileds), заполняем их в админке страницы и выводим в шаблоне кусками кода:

<?php echo get_field('text_for_slider_first_frame'); ?>

и

<?php echo get_field('text_for_slider_second_frame'); ?>

то есть — текст для первого кадра и текст для второго кадра.

Так это все сейчас работает, но мы усложним задачу. Предположим, я не знаю, сколько будет слайдов. Клиент будет эти слайды добавлять. Естественно, он не станет делать это через Custom Fields в админе, у него должно быть все готово для заполнения через админку страницы.

Мыслим логически — нам нужно, чтобы был какой-то механизм, который выводит все кастомные поля, пока они есть, внутри карусели.

Для этих целей есть расширение для ACF, называется ACF Repeater. Я не в курсе, платное ли оно, мне досталось в наследство на работе, даю сюда на скачивание:

download_me

Скачайте архив, идите в Плагины > Добавить новый > Загрузить плагин > выбираете свой зип > аплоад > активировать, готово.

Теперь идем в наши Произвольные поля. Добавляем поле и когда выбираем тип (Field Type) — вот он наш родной — Repeater, то есть — Повторитель.

s1

Как выводить поля с помощью ACF Reapeater?

Согласно документации, в репитере выводим поля так:

<?php

// check if the repeater field has rows of data
if( have_rows('repeater_field_name') ):

 // loop through the rows of data
 while ( have_rows('repeater_field_name') ) : the_row();

 // display a sub field value
 the_sub_field('sub_field_name');

 endwhile;

else :

 // no rows found

endif;

?>

Ну, с богом. Открываем админку наших ACF. Добавляем поле. Для понятности использую названия из приведенного выше кода. Поле называем repeater_field_name. Как только вы выбрали Тип поля — Repeater, у вас появится дополнительный ряд ВНУТРИ нашего поля, вложенный, как матрешка:

s2

Внутри этой матрешки жмем также Add sub_filed, появляется окно для заполнения, это саб_поле мы называем sub_field_name. Апдейтим всё.

Шагаем в нашу страницу Home Page. Видим, что новосозданное поле появилось:

s3

Жмем Add Row (Добавить ряд). В появившемся поле пишем наш текст (у меня bla-bla):

s4

Готово. Обновим страницу в админке, вставим код в шаблон и получим на выходе bla-bla на фронте.

Добавим в админке страницы еще пару полей, чтобы теперь вывести в карусели.

Откроем наш шаблон page.php в редакторе и вставим код:

<div class="carousel_bg">
 <div class="container">
 <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
 <!-- Indicators -->
 <ol class="carousel-indicators">
 <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
 <li data-target="#carousel-example-generic" data-slide-to="1"></li>
 </ol>
 
 <!-- Wrapper for slides -->
 <div class="carousel-inner" role="listbox">
 <?php
 if( have_rows('repeater_field_name') ): 
 while ( have_rows('repeater_field_name') ) : the_row();
 ?>
 <div class="item active screen08">
 <div class="container">
 <h1><?php the_sub_field('sub_field_name'); ?></h1>
 </div>
 </div><!-- /item -->
 <?php endwhile;
 endif; 
 ?>
 </div>
 </div>
 </div>
</div><!-- /row -->


Если перевести наш код на русский язык, то значит следующее:

if( have_rows('repeater_field_name') ): // ЕСЛИ есть ряды для поля repeater_field_name
while ( have_rows('repeater_field_name') ) : the_row(); // ПОКА эти ряды идут - выводить РЯД

Ставим вывод айтема карусели, закрываем endwhile, закрываем endif.

Обновим нашу страницу, и что же мы видим? Оба текста вылезли одновременно, карусель не крутится. Ну конечно же, мы задали цикл «выводить пока» для куска:

<div class="item active screen08">
...
</div>

А ведь что это значит для бутстрапа? Что на выходе ОБА айтема у нас активны (active). Как же нам сделать, чтобы только первый айтем (кадр) был активным? Очень просто, создаем переменную php:

<?php
$active = 'active';
?>

Вставляем его ДО цикла while, а уже внутри цикла while, после прохождения первого круга (выведения первого айтема) указываем для переменной $active пустое значение. И внутри классов айтема вместо класса вставляем переменную $active. Таким образом, она выведется 1 раз, а потом будет пустое значение. Выглядит так:

<?php
if( have_rows('repeater_field_name') ):
$active = 'active';
while ( have_rows('repeater_field_name') ) : the_row();
?>
<div class="item <?php echo $active ?> screen08">
<div class="container">
<h1><?php the_sub_field('sub_field_name'); ?></h1>
</div>
</div><!-- /item -->
<?php $active = '';
endwhile;
endif;
?>

Все заработало. Бутстрап дальше подхватывает и уже автоматом определяет класс active для остальных активных кадров.

Но осталась маленькая проблемка. Что делать с кружками — на которые тыкаешь, чтобы листать кадры? Сейчас их два, потому что в коде два, это просто приятное совпадение. Но если вы добавите еще 10 рядов (кадров), то кружков останется по-прежнему 2.

Итак. Очевидно, мы должны запустить тот же цикл для кружков, и использовать ту же переменную $active для активного кружка.

Рассмотрим внимательнее кусок бутстраповского кода, для вывода индикаторов (кружочков):

<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>

Мы видим, что кроме класса active у нас еще есть data-slide-to. Это значит — «крутить к» такому-то слайду на тык. Туда нам тоже нужно вогнать переменную, что делается достаточно просто. Мы также делаем переменную, например $num, ДО цикла while присваиваем ей значение 0 (не забываем — в программировании счет начинается с нуля), а до закрытия цикла while увеличиваем эту переменную на 1. Таким образом на следующем круге вывода li  data-slide-to будет равно 1, потом 2 и т.п. — пока не кончатся слайды.

Код:

<?php 
 $active = 'active';
 $num = 0;
 while ( have_rows('repeater_field_name') ) : the_row();
 ?>
 
 <li data-target="#carousel-example-generic" data-slide-to="<?php echo $num ?>" class="<?php echo $active ?>"></li>
 
 
 <?php 
 $active = '';
 $num += 1;
 endwhile; ?>


Сейчас мы видим, что код целиком для карусели можно оптимизировать, так как цикл if повторяется дважды. Вынесем его за пределы карусели. Это также решит еще одну проблему — что, если клиент захочет карусель убрать? Очевидно, он пойдет в админку страницы и просто удалит все кадры. Но в верстке страницы она останется, только с пустыми кадрами! Поэтому НУЖНО вынести условие if (если существуют ряды) за пределы карусели. При отстутствии рядов (кадров, кастомного репитера) карусель не выведется вообще.

Окончательный код:

<?php if( have_rows('repeater_field_name') ): ?>
 <div class="carousel_bg">
 <div class="container">
 <div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
 <!-- Indicators -->
 <ol class="carousel-indicators">
 <?php 
 $active = 'active';
 $num = 0;
 while ( have_rows('repeater_field_name') ) : the_row();
 ?>
 <li data-target="#carousel-example-generic" data-slide-to="<?php echo $num ?>" class="<?php echo $active ?>"></li>
 <?php 
 $active = '';
 $num += 1;
 endwhile; ?>
 </ol>
 <!-- Wrapper for slides -->
 <div class="carousel-inner" role="listbox">
 <?php
 $active = 'active';
 while ( have_rows('repeater_field_name') ) : the_row();
 ?>
 <div class="item <?php echo $active ?> screen08">
 <div class="container">
 <h1><?php the_sub_field('sub_field_name'); ?></h1>
 </div>
 </div><!-- /item -->
 <?php $active = '';
 endwhile;
 ?>
 </div>
 </div>
 </div>
</div><!-- /row -->
<?php endif; ?>

Я думаю, этого достаточно, чтобы понять, как вывести в слайдах картинки, подписи и любой другой контент.

Как выводить в бутстрап-карусели посты вордпресс — рассмотрим в другом уроке.