ACF Repeater: вывод строк без пустой разметки
Как вывести только заполненные строки ACF Repeater: проверка подполей, безопасный PHP-код и отсутствие пустых карточек.

Чтобы ACF Repeater не оставлял пустые карточки и контейнеры, сначала проверьте значения каждой строки, соберите только заполненные элементы и лишь затем откройте HTML-блок. Проверки одного have_rows() недостаточно: строка может существовать, но её подполя останутся пустыми.
Ниже пример для блока услуг с названием и описанием. Он показывает, куда вставить код, как обрабатывать необязательную ссылку и как убедиться, что пустая строка не создаёт разметку.
Что такое Repeater и почему появляются пустые блоки
Repeater — поле ACF PRO, в котором редактор добавляет несколько одинаковых строк. Внутри каждой строки находятся подполя: например, название, описание и ссылка. Шаблон часто выводит HTML для каждой строки сразу. Если редактор добавил строку и не заполнил её, на странице появляется пустая карточка. Если все строки пустые, может остаться и пустой заголовок секции.
Функция have_rows() сообщает, что у поля есть строки, но не проверяет содержимое подполей. Официальная документация Repeater описывает и цикл have_rows(), и получение массива через get_field(). Для проверки содержимого всех строк до вывода обёртки удобно использовать массив.
Подготовьте поля в ACF
- В группе полей добавьте Repeater с именем
service_items. - Внутри него создайте текстовое поле
title, многострочное текстовое полеdescriptionи необязательное поле Link с именемlink. - Привяжите группу полей к странице, на которой должен появиться блок. Сохраните группу.
Имена полей в коде должны совпадать с Field Name в ACF, а не с подписями, которые видит редактор. Repeater доступен в ACF PRO; на сайте с бесплатной версией или без активного ACF этот тип поля недоступен.
Код: соберите заполненные строки и выведите блок
Куда вставить: в PHP-файл шаблона дочерней темы, например page-services.php, или в подключаемый template part. Вставьте фрагмент в место, где должен появиться блок услуг. Не вставляйте PHP в редактор страницы и не изменяйте файлы плагина ACF. Если шаблон уже находится внутри PHP, не добавляйте второй открывающий тег <?php.
<?php
$service_items = array();
if ( function_exists( 'get_field' ) ) {
$rows = get_field( 'service_items', get_the_ID() );
if ( is_array( $rows ) ) {
foreach ( $rows as $row ) {
if ( ! is_array( $row ) ) {
continue;
}
$title = isset( $row['title'] ) && is_string( $row['title'] )
? trim( $row['title'] )
: '';
$description = isset( $row['description'] ) && is_string( $row['description'] )
? trim( $row['description'] )
: '';
if ( '' === $title || '' === $description ) {
continue;
}
$link = isset( $row['link'] ) && is_array( $row['link'] )
? $row['link']
: array();
$service_items[] = array(
'title' => $title,
'description' => $description,
'url' => isset( $link['url'] ) && is_string( $link['url'] )
? $link['url']
: '',
);
}
}
}
?>
<?php if ( $service_items ) : ?>
<section class="service-list" aria-labelledby="service-list-title">
<h2 id="service-list-title">Наши услуги</h2>
<ul class="service-list__items">
<?php foreach ( $service_items as $item ) : ?>
<li class="service-list__item">
<h3><?php echo esc_html( $item['title'] ); ?></h3>
<p><?php echo esc_html( $item['description'] ); ?></p>
<?php if ( '' !== $item['url'] && esc_url( $item['url'] ) ) : ?>
<a href="<?php echo esc_url( $item['url'] ); ?>">Подробнее</a>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
</section>
<?php endif; ?>
Разбор после кода
function_exists( 'get_field' )проверяет, доступна ли функция ACF. При отключённом плагине шаблон не остановится из-за вызова неизвестной функции.get_field()получает строки Repeater. Если поле пустое или вернулось значение другого типа, код оставляет массив$service_itemsпустым.trim()убирает пробелы по краям. Строка из одних пробелов не станет карточкой. В примере обязательны и название, и описание; если в вашем дизайне описание необязательно, измените именно это условие.- Ссылка необязательна. Если поле Link пусто или URL не проходит проверку
esc_url(), тег<a>не выводится. - Тег
<section>появляется только после проверки готового массива. Поэтому при отсутствии заполненных строк не остаются пустые заголовок, список и карточки. esc_html()выводит текст как текст, аesc_url()очищает адрес ссылки перед выводом. Для поля WYSIWYG с разрешённой разметкой нужен другой вариант, напримерwp_kses_post(); не заменяйте им экранирование обычного текста без причины. Подробнее об этом — в статье про безопасный вывод полей ACF.
Что должно получиться
Если заполнены две строки из трёх, на странице будут две карточки. Строка без названия или описания пропускается. Если заполненных строк нет или ACF отключён, секция целиком не выводится. В каждой карточке ссылка появляется только при наличии допустимого URL.
Как проверить
- На тестовой странице добавьте одну полностью заполненную строку, одну пустую и одну строку с пробелами вместо названия. Сохраните страницу.
- Откройте страницу без входа в админку. Должна появиться одна карточка без пустых элементов списка.
- Очистите ссылку в заполненной строке и сохраните страницу. Карточка должна остаться, а ссылка «Подробнее» исчезнуть.
- Очистите все строки и обновите страницу. Убедитесь, что не осталось заголовка «Наши услуги» и пустого списка.
- Проверьте ссылку, заголовки и отображение на узком экране. Если стили добавляете впервые, подключайте CSS через WordPress API; пример есть в руководстве по wp_enqueue.
Если не работает
- Вообще ничего не видно. Проверьте, что ACF PRO активен, группа полей назначена нужной странице, а
service_itemsсовпадает с именем поля. - Строки есть, но карточек нет. В этом примере название и описание обязательны. Заполните оба поля и проверьте имена
titleиdescription. - Ссылка не появляется. Убедитесь, что подполе имеет тип Link и возвращает массив. При типе URL настройте код под строковое значение.
- Разметка появилась не на той странице. Проверьте, какой шаблон использует страница и к какой записи обращается
get_the_ID(). В нестандартном цикле передайте явный ID нужной страницы. - После вставки сайт показывает критическую ошибку. Восстановите копию шаблона, проверьте кавычки и скобки. Пошаговая диагностика описана в статье о критической ошибке WordPress.
- Правка пропала после обновления темы. Перенесите шаблон в дочернюю тему, чтобы обновление родительской темы не заменило файл. Начать можно с инструкции по дочерней теме.
Официальные источники
Поведение Repeater и функции для работы со строками описаны в документации ACF Repeater и have_rows(). Правила вывода текста и ссылок сверяйте со справкой WordPress по экранированию.

