ACF Repeater (повторитель) – AJAX загрузка

Сегодня разберёмся, как реализовать загрузку полей ACF Repeater (повторитель) с помощью технологии AJAX. При нажатии на кнопку будем подгружать вложенные поля (пусть это будут изображения).

ACF Repeater Images

Выведем изображения, предварительно создав три переменные:

  • $total_rows — получим общее число вложенных полей;
  • $count — заведём счётчик для подсчёта;
  • $number — добавим ограничение, по сколько вложенных полей (изображений) выводить при каждом AJAX запросе.
<?php
$total_rows = count(get_field("acf_repeater_row")); # всего изображений
$count = 0;  # счётчик
$number = 8; # сколько изображений отображать на каждой странице
?>

<?php
// Если есть вложенные поля (изображения)
if (have_rows("acf_repeater_row")) { ?>

    <div class="ajax-container">

        <?php
        while (have_rows("acf_repeater_row")) {
            the_row();

            if ($count == $number) {
                break; # если показали все изображения, выходим из цикла
            } ?>

            <?php $img_object = get_sub_field("acf_repeater_field"); ?>

            <a data-fancybox="gallery" href="<?php echo esc_url($img_object["sizes"]["large"]); ?>">
                <img src="<?php echo esc_url($img_object["sizes"]["medium"]); ?>" alt="alt">
            </a>

            <?php
            $count++;
        } ?>

    </div>

<?php } ?>

<button class="btn acf-loadmore" onclick="javascript: acf_repeater_show_more();"
    <?php if ($total_rows < $count) : ?> style="display: none;" <?php endif; ?>>
    показать ещё
</button>

Далее, под кнопкой, разместим скрипт AJAX загрузки изображений, добавленных при помощи повторителя ACF.

<!-- AJAX загрузка -->
<script>
    let my_repeater_field_post_id = <?php echo $post-> ID; ?>;
    let my_repeater_field_offset = <?php echo $number; ?>;
    let my_repeater_field_nonce = "<?php echo wp_create_nonce("my_repeater_field_nonce"); ?>";
    let my_repeater_ajax_url = "<?php echo admin_url("admin-ajax.php"); ?>";
    let my_repeater_more = true;

    function acf_repeater_show_more() {
        // делаем AJAX запрос
        jQuery.post(my_repeater_ajax_url, {
            // AJAX, который мы настроили в PHP
            "action": "acf_repeater_show_more",
            "post_id": my_repeater_field_post_id,
            "offset": my_repeater_field_offset,
            "nonce": my_repeater_field_nonce
        }, function (json) {
            // добавляем контент в контейнер
            // этот идентификатор должен соответствовать контейнеру
            // к которому вы хотите добавить контент
            jQuery(".ajax-container").append(json["content"]);
            // обновим смещение
            my_repeater_field_offset = json["offset"];
            // проверим, есть ли еще что загрузить
            if (!json["more"]) { // если нет, то скроем кнопку загрузки
                jQuery(".acf-loadmore").css("display", "none");
            }
        }, "json");
    }
</script>

functions/load-more-acf.php

Создадим и подключим файл functions/load-more-acf.php:

require get_template_directory() . '/functions/load-more-acf.php';

Затем добавим в него следующий код.

<?php
/**
 * ACF AJAX подгрузка
 */

// добавляем action для авторизованных пользователей
add_action("wp_ajax_acf_repeater_show_more", "acf_repeater_show_more");
// добавляем action для не авторизованных пользователей
add_action("wp_ajax_nopriv_acf_repeater_show_more", "acf_repeater_show_more");

function acf_repeater_show_more()
{
    // валидация Nonce («Одноразовые числа»)
    if (!isset($_POST["nonce"]) || !wp_verify_nonce($_POST["nonce"], "my_repeater_field_nonce")) {
        exit;
    }
    // убедимся, что у нас есть другие значения
    if (!isset($_POST["post_id"]) || !isset($_POST["offset"])) {
        return;
    }
    $show = 3; // по сколько отображать
    $start = $_POST["offset"];
    $end = $start + $show;
    $post_id = $_POST["post_id"];
    // используем объектный буфер для захвата вывода html (объектные буферы упрощают работу с кодом)
    // в качестве альтернативы вы можете создать переменную вроде $html
    // и добавлять содержимое в эту строку
    ob_start();
    if (have_rows("acf_repeater_row", $post_id)) {
        $total = count(get_field("acf_repeater_row", $post_id));
        $count = 0;

        while (have_rows("acf_repeater_row", $post_id)) {
            the_row();
            if ($count < $start) {
                // продолжаем показывать и увеличивать счётчик
                $count++;
                continue;
            }
            ?>
            <?php $img_object = get_sub_field("acf_repeater_field"); ?>

            <a data-fancybox="gallery" href="<?php echo esc_url($img_object["sizes"]["large"]); ?>">
                <img src="<?php echo esc_url($img_object["sizes"]["medium"]); ?>" alt="alt">
            </a>

            <?php
            $count++;
            if ($count == $end) {
                break; # если показали все строки повторителя, выходим из цикла
            }
        }
    }
    $content = ob_get_clean();
    // проверим, показали ли мы последний элемент
    $more = false;
    if ($total > $count) {
        $more = true;
    }
    // выводим наши 3 значения в виде массива в кодировке json
    echo json_encode(array("content" => $content, "more" => $more, "offset" => $end));
    exit;
}

Или же можно просто добавить php код прямо в functions.php.

Итак, мы сегодня реализовали AJAX загрузку изображений, добавленных с помощью плагина Advanced Custom Fields с типом «Повторитель».