ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом

ACF поля в WordPress: как создавать и выводить метаполя — полный гайд с кодом

Быстрый ответ: Advanced Custom Fields (ACF) — самый популярный плагин для создания метаполей в WordPress (5+ млн установок). Он позволяет добавлять любые поля — текст, изображения, галереи, повторители, гибкие контентные блоки — без написания кода через админку, а выводит их через простые PHP-функции вроде get_field() и the_field(). Для работы потребуется ACF PRO (бесплатная версия тоже есть, но без повторителей, гибкого контента и страниц опций). Установка занимает 2 минуты, а первый кастомный блок появится на сайте через 10 минут после прочтения этой статьи.

Что такое ACF и зачем он нужен разработчику

Advanced Custom Fields — это плагин, который превращает стандартную WordPress-админку в конструктор контента. Без ACF разработчику приходится либо писать метабоксы вручную (через add_meta_box()), либо использовать Gutenberg и надеяться, что клиент не сломает вёрстку.

ACF решает три главные задачи:

  • Даёт интерфейс клиенту — удобные поля с подсказками, валидацией и понятными названиями
  • Ускоряет разработку — один раз настроил группу полей и используешь на любом типе записей
  • Стандартизирует данные — все метаполя хранятся в едином формате, легко выводятся и фильтруются

В портфолио наших проектов на delai-sait.ru ACF используется почти везде — от карточек товаров до настроек темы.

Установка и первые настройки

Бесплатная версия vs PRO

Функция ACF (бесплатно) ACF PRO
Текстовые поля, wysiwyg, изображения ✅ ✅
Галерея, файлы ✅ ✅
Повторитель (Repeater) ❌ ✅
Гибкий контент (Flexible Content) ❌ ✅
Страницы опций (Options Pages) ❌ ✅
Клонирование групп полей ❌ ✅
Цена Бесплатно ~$49–$249/год

Вывод: для серьёзной разработки нужен ACF PRO. Повторители и гибкий контент — это 80% задач, которые решает плагин.

Установка через composer (рекомендуемый способ)

composer require wpengine/advanced-custom-fields-pro

Для бесплатной версии:

composer require advanced-custom-fields/advanced-custom-fields

Или скачайте ZIP в репозитории плагинов WordPress — wordpress.org/plugins/advanced-custom-fields.

Создание первой группы полей через админку

После активации ACF в меню появится пункт «Custom Fields». Нажимаем «Add New» — и попадаем в конструктор.

Шаг 1. Настройка правил отображения

Главное в ACF — правила (Location Rules). Именно они определяют, на каких страницах показывать группу полей.

Правило: Post Type == product
→ Группа полей появится на всех товарах WooCommerce

Правило: Post Type == post
И правило: Post Category == news
→ Группа полей появится только в новостях

Правило: Taxonomy == category
→ Работает для термов таксономий

Правила можно комбинировать (И/ИЛИ), создавая сложные сценарии отображения. Подробнее о разработке WordPress читайте в других статьях блога.

Шаг 2. Добавление полей

ACF поддерживает десятки типов полей. Самые популярные:

Тип поля Назначение Возвращаемое значение
Text Короткий текст (название, артикул, тег) string
WYSIWYG Editor Текст с форматированием string (HTML)
Image Одно изображение ID, URL или array
Gallery Несколько изображений array из ID/URL
File PDF, документы ID, URL или array
Repeater Повторяющийся набор полей array (PRO)
Flexible Content Секции разного типа array (PRO)
Select / Checkbox / Radio Выбор из вариантов string / array
True/False Вкл/Выкл переключатель bool
Google Map Координаты на карте array (lat, lng, адрес)
Color Picker Выбор цвета HEX-строка
Date Picker / Time Picker Дата и время string (Ymd, H:i:s)

Шаг 3. Сохранение и проверка

После сохранения группы полей откройте запись нужного типа — под редактором появятся настроенные поля. Заполните их и обновите запись.

Вывод полей в шаблоне: get_field() и the_field()

Это основа работы с ACF. Две главные функции:

  • get_field('field_name', $post_id) — возвращает значение поля (можно присвоить переменной)
  • the_field('field_name', $post_id) — сразу выводит значение (echo)

Базовый пример для текстового поля:

<?php
// Вывод названия бренда (text-поле)
$brand = get_field('brand');
if ($brand) : ?>
    <span class="product-brand">Бренд: <?php echo esc_html($brand); ?></span>
<?php endif; ?>

Изображение (Image)

<?php
$image = get_field('hero_image');
if ($image) :
    // $image возвращает массив с id, url, alt, width, height
    $img_url = $image['url'];
    $img_alt = $image['alt'];
    $img_width = $image['width'];
    $img_height = $image['height'];
?>
    <img src="<?php echo esc_url($img_url); ?>"
         alt="<?php echo esc_attr($img_alt); ?>"
         width="<?php echo $img_width; ?>"
         height="<?php echo $img_height; ?>"
         loading="lazy">
<?php endif; ?>

Совет: используйте esc_html() и esc_url() для безопасного вывода. Всегда проверяйте значение через if — поле может быть пустым.

Работа с повторителем (Repeater)

Повторитель — одна из самых востребованных функций ACF PRO. Позволяет добавлять неограниченное количество повторяющихся блоков.

Пример: контактные данные организации

<?php
if (have_rows('contacts')) : ?>
    <ul class="contacts-list">
    <?php while (have_rows('contacts')) : the_row();
        $type = get_sub_field('contact_type'); // select: phone, email, address
        $value = get_sub_field('contact_value');
        $label = get_sub_field('contact_label');
    ?>
        <li class="contact-item contact-<?php echo $type; ?>">
            <strong><?php echo esc_html($label); ?>:</strong>
            <?php if ($type === 'email') : ?>
                <a href="mailto:<?php echo esc_attr($value); ?>">
                    <?php echo esc_html($value); ?>
                </a>
            <?php elseif ($type === 'phone') : ?>
                <a href="tel:<?php echo esc_attr(preg_replace('/[^0-9+]/', '', $value)); ?>">
                    <?php echo esc_html($value); ?>
                </a>
            <?php else : ?>
                <?php echo esc_html($value); ?>
            <?php endif; ?>
        </li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>

Ключевые функции для повторителя:

  • have_rows('field_name') — проверяет, есть ли строки (аналог have_posts())
  • the_row() — переключает контекст на текущую строку
  • get_sub_field() / the_sub_field() — получают значение поля внутри строки

Гибкий контент (Flexible Content) — конструктор секций

Flexible Content — это «конструктор» страницы. Вы определяете типы секций (блоков), а клиент собирает страницу как в Lego: добавил секцию «Герой», потом «Преимущества», потом «Отзывы».

Регистрация макета:

<?php
// В админке ACF создаётся поле типа Flexible Content с именем 'page_sections'
// Добавляем макеты (layouts): hero, features, testimonials, cta

// В шаблоне:
if (have_rows('page_sections')) :
    while (have_rows('page_sections')) : the_row();
        $layout = get_row_layout();
?>
        <section class="section section-<?php echo $layout; ?>">
        <?php
        switch ($layout) {
            case 'hero':
                $title = get_sub_field('hero_title');
                $bg = get_sub_field('hero_background');
                ?>
                <div class="hero" style="background: url(<?php echo esc_url($bg['url']); ?>)">
                    <h1><?php echo esc_html($title); ?></h1>
                </div>
                <?php
                break;

            case 'features':
                if (have_rows('features_list')) :
                    ?><div class="features-grid"><?php
                    while (have_rows('features_list')) : the_row();
                        $icon = get_sub_field('feature_icon');
                        $text = get_sub_field('feature_text');
                        ?>
                        <div class="feature-card">
                            <img src="<?php echo esc_url($icon['url']); ?>" alt="">
                            <p><?php echo esc_html($text); ?></p>
                        </div>
                        <?php
                    endwhile;
                    ?></div><?php
                endif;
                break;

            case 'testimonials':
                // ...вывод отзывов
                break;

            case 'cta':
                $btn_text = get_sub_field('cta_text');
                $btn_link = get_sub_field('cta_link');
                ?>
                <div class="cta-block">
                    <a href="<?php echo esc_url($btn_link); ?>" class="btn btn-primary">
                        <?php echo esc_html($btn_text); ?>
                    </a>
                </div>
                <?php
                break;
        }
        ?>
        </section>
    <?php endwhile;
endif;

Этот подход используется в лендингах, которые мы делаем в delai-sait.ru — клиент может редактировать секции, не трогая код.

Страницы опций (Options Pages)

Options Pages — глобальные настройки для всего сайта: контакты в футере, скрипты аналитики, соцсети, настройки компании.

Регистрация через functions.php:

<?php
if (function_exists('acf_add_options_page')) {
    acf_add_options_page([
        'page_title'    => 'Настройки сайта',
        'menu_title'    => 'Настройки темы',
        'menu_slug'     => 'theme-settings',
        'capability'    => 'edit_theme_options',
        'redirect'      => false,
        'icon_url'      => 'dashicons-admin-settings',
    ]);
}

Вывод в шаблоне:

<?php
$phone = get_field('company_phone', 'option');
$email = get_field('company_email', 'option');
$address = get_field('company_address', 'option');
?>
<footer class="site-footer">
    <p>Телефон: <?php echo esc_html($phone); ?></p>
    <p>Email: <a href="mailto:<?php echo esc_attr($email); ?>"><?php echo esc_html($email); ?></a></p>
    <p><?php echo esc_html($address); ?></p>
</footer>

Второй параметр 'option' указывает ACF искать значение в глобальных опциях, а не в текущей записи.

Сохранение и синхронизация полей через PHP (Local JSON)

Для продакшена настройки ACF лучше хранить в коде, а не в БД. ACF поддерживает Local JSON — автосохранение групп полей в JSON-файлы темы.

<?php
// В functions.php указываем путь к JSON-файлам
add_filter('acf/settings/save_json', function ($path) {
    return get_stylesheet_directory() . '/acf-json';
});

add_filter('acf/settings/load_json', function ($paths) {
    $paths[] = get_stylesheet_directory() . '/acf-json';
    return $paths;
});

Теперь при сохранении группы полей ACF запишет JSON-файл в папку темы. При переносе на другой сервер достаточно скопировать тему — поля подтянутся автоматически.

Пример JSON-файла:

{
    "key": "group_6458ea2d1f4a7",
    "title": "Карточка товара",
    "fields": [
        {
            "key": "field_6458ea4b1f4a8",
            "label": "Артикул",
            "name": "sku",
            "type": "text"
        },
        {
            "key": "field_6458ea6b1f4a9",
            "label": "Цена со скидкой",
            "name": "sale_price",
            "type": "number"
        }
    ],
    "location": [
        [
            {
                "param": "post_type",
                "operator": "==",
                "value": "product"
            }
        ]
    ]
}

ACF + WP_Query: фильтрация по метаполям

Одно из главных преимуществ метаполей — возможность фильтровать записи по их значениям.

<?php
// Вывести товары с ценой выше 5000
$products = new WP_Query([
    'post_type'      => 'product',
    'posts_per_page' => 10,
    'meta_query'     => [
        [
            'key'     => 'price',
            'value'   => 5000,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ]
    ]
]);

Сложный запрос с несколькими условиями:

<?php
$projects = new WP_Query([
    'post_type'      => 'project',
    'posts_per_page' => -1,
    'meta_query'     => [
        'relation' => 'AND',
        [
            'key'     => 'project_status',
            'value'   => 'completed',
            'compare' => '='
        ],
        [
            'key'     => 'project_budget',
            'value'   => 100000,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ],
        [
            'key'     => 'project_year',
            'value'   => 2025,
            'type'    => 'NUMERIC',
            'compare' => '>='
        ]
    ],
    'orderby'  => 'meta_value_num',
    'meta_key' => 'project_budget',
    'order'    => 'DESC'
]);

Важно: типы NUMERIC и DATE работают значительно быстрее, чем сравнение строк. Всегда указывайте 'type' для числовых полей.

ACF vs ручные метабоксы: что выгоднее

Критерий ACF PRO Ручные метабоксы
Скорость разработки Быстро — настройка через GUI В 3–5 раз дольше
Гибкость типов полей 30+ типов из коробки Писать каждое поле вручную
Повторители Есть (Repeater, Flexible Content) Писать JS-решение с нуля
Производительность Кэширование запросов Зависит от реализации
Совместимость с REST API ACF-to-REST API Нужно регистрировать поля вручную
Стоимость От $49/год (PRO) Бесплатно (но время разработчика дороже)
Поддержка WP Engine + комьюнити Только вы
Переносимость (Local JSON) Автоматически Нужно переносить код

Когда без ACF можно обойтись:

  • Нужно всего 1–2 простых поля (текст + изображение)
  • Проект на бесплатном плагине с уже встроенными полями
  • Жёсткие требования к производительности (миллионы записей)

Во всех остальных случаях ACF PRO окупается за первый же час работы. Если вам нужна помощь с разработкой — свяжитесь с нами, мы используем ACF в каждом проекте.

Распространённые ошибки и как их избежать

  1. Не указывать $post_id в get_field() — в цикле WordPress работает, но за его пределами (в сайдбаре, футере) может вернуть null. Всегда передавайте ID записи.
  2. Забывать esc_html() — если поле может содержать HTML, используйте esc_html(). Для WYSIWYG — the_field() без экранирования (в нём уже разрешённый HTML).
  3. Тяжёлые запросы с meta_query — на больших сайтах (10k+ записей) используйте индексы в БД и транзиентное кэширование.
  4. Хранение настроек в БД — используйте Local JSON для продакшена. Если staging и production расходятся по полям — ждите багов.
  5. Игнорировать update_preview — для превью Gutenberg ACF не подгружается автоматически, проверяйте на опубликованной странице.
300x250 20

Заключение

ACF — must-have инструмент для любого WordPress-разработчика. Он экономит часы рутинной работы, даёт клиенту понятный интерфейс и делает код чище и поддерживаемее.

Мы в delai-sait.ru используем ACF PRO в каждом проекте — от лендингов до интернет-магазинов. Если вам нужна консультация по внедрению или разработка сайта на WordPress — напишите нам, обсудим задачи и предложим решение.

Полезные ссылки:

7 8 2
Чем отличается get_field() от the_field()?

get_field() возвращает значение (нужно для присваивания переменной или проверки), the_field() сразу выводит его (echo). Разницы в производительности нет — выбирайте по задаче.

Нужен ли ACF PRO или хватит бесплатной версии?

Бесплатной версии достаточно для простых полей (текст, изображение, wysiwyg). Если нужны повторители, гибкий контент или страницы опций — без ACF PRO не обойтись.

Как перенести ACF-поля с одного сайта на другой?

Лучший способ — Local JSON. Настройте путь к папке acf-json в functions.php и просто скопируйте файлы.

Влияет ли ACF на скорость сайта?

ACF добавляет ~100-300 мс к генерации страницы. Проблемы возникают при неоптимальных WP_Query с meta_query на больших объёмах данных.

Как вывести ACF-поле в REST API?

Установите плагин ACF-to-REST API или добавьте acf_register_rest_fields() в functions.php.

Можно ли использовать ACF с WooCommerce?

Да, ACF отлично работает с WooCommerce. Можно добавлять поля к товарам, категориям, заказам и пользователям.

Что лучше: ACF, Meta Box или Carbon Fields?

ACF — стандарт индустрии, самый популярный и документированный. Meta Box — достойная альтернатива. Carbon Fields — легковесный вариант.

Как получить ID вложенного поля повторителя?

Используйте get_sub_field_object(‘field_name’) — он вернёт объект поля с ключом ID.

Поделиться:
Telegram ВКонтакте