Как создать повторяемые блоки контента через ACF
За 10 лет работы с WordPress я перепробовал, кажется, все способы, которыми только можно было структурировать контент для заказчиков — от простых визуальных редакторов до собственных наборов метаполей. В какой-то момент в моём арсенале появился Advanced Custom Fields (ACF), и вот тут я впервые почувствовал, что управляю не просто сайтами, а целыми конструкторами страниц. Особенно сильно на мой подход повлияли две его “фишки”: Repeater и Flexible Content.
Давайте присядем и разберём, почему они настолько меняют ежедневную рутину.
Поначалу я работал “по-старинке” — под каждый отдельный кусочек информации верстал своё поле: нужно клиенту прописать пять преимуществ продукта? Завожу отдельно “Преимущество 1”, “Преимущество 2”… Вдруг захотелось добавить шестое — здравствуйте, лезем в код, плодим новые строчки в базе данных и чуть-чуть теряем веру в человечество. К этому довольно быстро теряешь терпение — но вариантов особо не было.
А вот когда я впервые попробовал Repeater Field из ACF, словно открыл для себя режим конструктора LEGO: просто задаёшь один блок-шаблон и разрешаешь клиенту добавлять столько копий, сколько душе угодно. Никакой возни с обновлением шаблона или базы — все настройки остаются прежними. На практике это радикально снизило число «пожарных» правок по вечерам и дало самим клиентам ощутить контроль над контентом — наконец-то они могут строить свои страницы сами, как из кубиков (в админке всё интуитивно и наглядно).
Если говорить честно, даже на крупных проектах такой подход позволил сократить время разработки модульных страниц с дней до часов. Реально чувствуется разница – когда тебе больше не приходится постоянно «догонять» пожелания клиента изменениями в коде.
Про Flexible Content расскажу отдельно — это уже прям целый level up!
Пошаговая настройка Repeater
Вот моя типичная последовательность действий при создании блока «Преимущества компании»:
Шаг 1. Создаю новую группу полей через ACF → Field Groups → Add New.
Шаг 2. Добавляю поле типа Repeater, называю его понятно — например, advantages.
Шаг 3. Внутри репитера создаю подполя:
- Иконка (тип Image)
- Заголовок (тип Text)
- Описание (тип Textarea)
Шаг 4. В настройках отображения указываю, на каких страницах или типах записей эта группа полей будет появляться.
После сохранения в редакторе страницы появляется интерфейс и можно добавлять сколько угодно блоков, менять их порядок простым drag-and-drop, удалять ненужные.
Вывод данных в шаблоне
Самая важная часть — правильно написать код для отображения. Вот пример, который я использую в файле шаблона:
<?php if( have_rows('advantages_list') ): ?>
<div class="advantages">
<?php while( have_rows('advantages') ): the_row();
$icon = get_sub_field('icon');
$title = get_sub_field('title');
$description = get_sub_field('description');
?>
<div class="advantage-item">
<?php if($icon): ?>
<img src="<?php echo esc_url($icon['url']); ?>" alt="<?php echo esc_attr($title); ?>">
<?php endif; ?>
<h3><?php echo esc_html($title); ?></h3>
<p><?php echo esc_html($description); ?></p>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
Обратите внимание на использование функций esc_html() и esc_url() — это не просто рекомендация, а критически важная практика безопасности. Я всегда экранирую вывод данных, независимо от того, насколько доверяю источнику контента.
Flexible Content — следующий уровень гибкости
Когда клиенту нужна не просто повторяемость одинаковых блоков, а возможность комбинировать разные типы контента, я использую Flexible Content Field. Это как конструктор LEGO.
В моей практике типичная структура для лендинга включает такие макеты (layouts):
- Text Block — обычный текстовый блок с заголовком
- Gallery — блок с несколькими изображениями
- Testimonial — блок отзыва с фото и цитатой
- CTA — призыв к действию с кнопкой
Клиент может выстроить страницу в любом порядке, комбинируя эти блоки как ему нужно.
Код для работы с Flexible Content чуть сложнее:
<?php if( have_rows('page_builder') ): ?>
<?php while( have_rows('page_builder') ): the_row();
if( get_row_layout() == 'text_block' ):
get_template_part('template-parts/blocks/text-block');
elseif( get_row_layout() == 'testimonial' ):
get_template_part('template-parts/blocks/testimonial');
elseif( get_row_layout() == 'cta' ):
get_template_part('template-parts/blocks/cta');
endif;
endwhile;
endif;
?>
Я вынес логику каждого блока в отдельные файлы через get_template_part() — это правило, которое я установил для себя после того, как один шаблон разросся до 800 строк кода и стал абсолютно нечитаемым.
Практические советы из личного опыта
Всегда используйте wrapper класс для проверки пустых полей. Даже если поле кажется обязательным, я проверяю его существование перед выводом. Это спасло меня от множества фатальных ошибок PHP на продакшене.
Ограничивайте максимальное количество повторений, если это логически оправдано. В настройках Repeater есть параметр Max, который предотвращает создание клиентом сотни ненужных блоков.
Именуйте поля осмысленно и последовательно. Когда работаешь с проектом через полгода после создания, названия типа field_1, field_2 превращаются в настоящий кошмар.
Используйте условную логику внутри репитеров. Например, если у меня есть выбор типа блока «с изображением» или «без изображения», поле загрузки картинки появляется только при выборе соответствующей опции.
Кеширование для производительности
На высоконагруженных проектах я обязательно кеширую вывод повторяющихся блоков, особенно если данных много. Использую transients API:
$cache_key = 'advantages_' . get_the_ID();
$cached_content = get_transient($cache_key);
if(false === $cached_content) {
// генерация контента через ACF
set_transient($cache_key, $cached_content, HOUR_IN_SECONDS);
}
Заключение
ACF превратил создание контентных страниц из головной боли разработчика в удобный процесс для клиента. За годы работы я убедился: инвестиции времени в правильную структуру полей на старте проекта окупаются многократно при последующей поддержке сайта. Главный принцип, которому я следую — думать не только о своём удобстве как разработчика, но и о том, насколько интуитивно клиент будет управлять контентом через несколько месяцев после запуска сайта.