Как создать повторяемые блоки контента через ACF

Как создать повторяемые блоки контента через 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):

  1. Text Block — обычный текстовый блок с заголовком
  2. Gallery — блок с несколькими изображениями
  3. Testimonial — блок отзыва с фото и цитатой
  4. 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 превратил создание контентных страниц из головной боли разработчика в удобный процесс для клиента. За годы работы я убедился: инвестиции времени в правильную структуру полей на старте проекта окупаются многократно при последующей поддержке сайта. Главный принцип, которому я следую — думать не только о своём удобстве как разработчика, но и о том, насколько интуитивно клиент будет управлять контентом через несколько месяцев после запуска сайта.