В этом уроке хотел бы совсем немного поговорить про repeater-поля (Complex fields) в плагине Carbon Fields и показать вам пару примеров.
Уже две недели я выхваливаю этот плагин, конечно же только потому что он мне понравился, я ни с кем не партнёрился.
Что такое repeater-поля?
Давайте я наверное сначала покажу вам пример, как это выглядит в админке:
На фото выше вы можете заметить, что мы можем добавлять какое-то количество блоков, причём разного типа (с текстом, с фото и с текстом и ссылкой), кроме того их можно менять местами.
Подобное поле на клиентском сайте используется для вывода вот этих блоков:
В самом конце урока вы найдёте видео, в котором я пошагово создавал эти блоки.
Создание повторяющегося поля
Вообще в самом плагине Carbon Fields это поле называется Complex, но все уже привыкли к названию repeater или повторяющиеся поля, потому что оно более подробно описывать, о чём вообще всё это.
Вот супер-лёгкий пример создания повторяющего поля:
Field::make( 'complex', 'truemisha_slider', 'Слайдер' ) ->add_fields( array( Field::make( 'text', 'title', 'Заголовок слайда' ), Field::make( 'image', 'photo', 'Изображение слайда' ), ) ),
И не забываем про хук carbon_fields_register_fields
и в самом начале кода в файле вызвать:
use Carbon_FieldsContainer; use Carbon_FieldsField;
Если вы забываете об этом, то рекомендую вернуться к вступительному уроку про Carbon Fields.
После вставки его в код, у вас появится:
Получение значений поля в коде
Окей, поля в админке есть, как теперь получить их значения? Помните в руководстве по Carbon Fields я говорил, что не для всех типов полей можно спокойно использовать get_post_meta() ? Вот complex field это как раз и есть такое поля. Поэтому мы будем использовать carbon_get_post_meta()
ну или ту функцию, которая предназначена для настроек таксономий, опций и так далее, в зависимости от того, где вы создаёте поля.
$slides = carbon_get_post_meta( get_the_ID(), 'truemisha_slider' ); if( $slides ) { foreach( $slides as $slide ) { // смысла в слайде ведь нет, если не используется фото?? if( ! $slide[ 'photo' ] ) { continue; // скипаем итерацию цикла, если нет фотки } echo '<div class="slide">'; echo wp_get_attachment_image( $slide[ 'photo' ] ); if( $slide[ 'title' ] ) { // empty() и isset() нет нужды использовать тут echo '<h2>' . esc_html( $slide[ 'title' ] ) . '</h2>'; } echo '</div>' } }
Код очень примерный, но я тем не менее старался сделать его максимально подробным, чтобы вы не забывали учитывать «проверки на дурака», например когда пользователь сайта не заполнил фотку или решил поразвлекаться с HTML-тегами внутри заголовка слайда.
Ширина полей внутри группы
Если вы взглянете на поля настроек нашего слайдера, то заметите, что поле заголовка какой-то невероятной длины, я поле изображения едва ли занимает 1/4 часть от экрана!
Хорошая новость – мы можем задавать ширину полей в процентах (работает на flex-basis
). Например у нас тут с вами два поля, причём для изображения нужно совсем немного места, я думаю 25% будет ок, а остальное можно оставить для заголовка. Но я попробовал такой вариант и решил разделить поля 50 на 50, так оказалось красивее, для этого я использовал метод set_width()
.
Field::make( 'complex', 'truemisha_slider', 'Слайдер' ) ->add_fields( array( Field::make( 'text', 'title', 'Заголовок слайда' )->set_width( 50 ), Field::make( 'image', 'photo', 'Изображение слайда' )->set_width( 50 ), ) ),
И вот результат:
Разные группы полей в пределах одного репитера
Хорошо, идём апгрейдить наш слайдер дальше – что если там будет не только фото, но и видео! Причём в любом порядке!
Тут на самом деле всё легко, чтобы в один репитер добавлять разные группы, мы всего лишь снова и снова используем метод add_fields()
.
Field::make( 'complex', 'truemisha_slider', 'Слайдер' ) ->add_fields( 'image', 'Изображение', array( Field::make( 'text', 'title', 'Заголовок слайда' ), Field::make( 'image', 'photo', 'Изображение слайда' ), ) ) ->add_fields( 'movie', 'Видос', array( Field::make( 'text', 'title', 'Заголовок слайда' ), Field::make( 'file', 'video', 'Видео слайда' ), ) ),
На скриншоте ниже понятно, что при нажатии на кнопку добавления группы, вы можете выбрать, какая это будет группа – с фото или с видео:
Ах да, когда будете выводить такое поле на сайте, то у каждого слайда появится параметр типа, а именно $slide[ '_type' ]
, который будет равен или image
или movie
.
Отображение в виде вкладок
Возможно вы не захотите, чтобы поля шли друг за другом вертикально, тогда хочу предложить вам ещё две опции – это отображение полей в виде горизонтальных и вертикальных вкладок, для этого мы будем использовать метод set_layout() непосредственно к комплексному полю.
Например:
Field::make( 'complex', 'truemisha_slider', 'Слайдер' )->set_layout( 'tabbed-horizontal' )
Получается:
Или например:
Field::make( 'complex', 'truemisha_slider', 'Слайдер' )->set_layout( 'tabbed-vertical' )
Получается:
Вложенность. Одно комплексное поле внутри другого комплексного поля.
Да – внутри репитера может быть ещё один репитер! 🤯
Ну и это прекрасно, я думаю. Правда я не знаю, как это можно применить к нашему примеру слайдера. Давайте сделаем как в официальной документации – заменим поле заголовка на репитер, т е возможность добавлять несколько текстовых элементов.
Field::make( 'complex', 'truemisha_slider', 'Слайдер' ) ->add_fields( array( Field::make( 'image', 'photo', 'Изображение слайда' ), Field::make( 'complex', 'slide_fragments', 'Надписи на слайде' ) ->add_fields( array( Field::make( 'text', 'fragment_text', 'Текст' ), Field::make( 'select', 'fragment_position', 'Расположение' ) ->add_options( array( 'Сверху слева', 'Сверху справа', 'Снизу слева', 'Снизу справа' ) ), )) )),
Ну и в админке это будет выглядеть вот так:
Установка максимального количества повторений полей
Тут легко – допустим мы не хотим, чтобы пользователи сайта добавляли сотни слайдов, которые естественно отразятся на скорости загрузки страниц, поэтому установим предел этому:
Field::make( 'complex', 'truemisha_slider', 'Слайдер' )->set_max( 5 ) // 5 слайдов это уже норм!
Это будет работать таким образом, что при добавлении 5-го слайда, кнопка добавления повторения поля будет исчезать – удобно!
Разрешаем или нет дублирование полей
У каждой повторяющейся группы полей рядом с кнопкой удаления есть кнопка дублирования группы:
Эту кнопку можно отключить методом set_duplicate_groups_allowed()
.
Field::make( 'complex', 'truemisha_slider', 'Слайдер' )->set_duplicate_groups_allowed( false )
Заголовки групп
Выше в примерах вы уже могли заметить, что я добавлял заголовки группам, но это были очень примитивные заголовки типо «Изображение» или «Видео», но самое интересное начинается тогда, когда к этим заголовкам мы можем добавлять ещё и значение одного из поля внутри группы!
Например использовав метод set_header_template()
и вот такой код:
Field::make( 'complex', 'truemisha_slider', 'Слайдер' ) ->add_fields( 'image', 'Изображение', array( Field::make( 'text', 'title', 'Заголовок слайда' ), Field::make( 'image', 'photo', 'Изображение слайда' ), ) ) ->set_header_template( ' <% if (title) { %> Изображение: <%- title %> % } %> ' ) ->add_fields( 'movie', 'Видос', array( Field::make( 'text', 'title', 'Заголовок слайда' ), Field::make( 'file', 'video', 'Видео слайда' ), ) ) ->set_header_template( ' <% if (title) { %> Видос: <%- title %> <% } %> ' ),
Мы получим очень классный результат:
Пример при ипользовании двух значений полей внутри заголовка:
->set_header_template( ' <% if (name) { %> Пассажир: <%- name %> <%- years ? "(" + years + ")" : "" %> <% } %> ' )